編輯:關於Android編程
RxJava在現在是一個非常前衛的異步框架,也是由於他非常新,所以比較難以駕馭。
像okhttp直接在onStop或者onDestroy 調用它的cancel方法就行了,但是Rxjava並沒有那麼簡單。
因為假如每次請求都得到Observable對象,然後再onStop中unsubscribe取消,這樣很不利於封裝。而且會造成代碼量很多,所以我找到了用rxlifecycle的解決方案。
先導包
compile 'com.trello:rxlifecycle:0.5.0'
compile 'com.trello:rxlifecycle-components:0.5.0'
然後寫RxActivity,原作者github上有源碼,我根據自己的情況稍微修改了一下。
import android.os.Bundle;
import android.support.annotation.CallSuper;
import android.support.annotation.NonNull;
import android.support.v4.app.FragmentActivity;
import com.trello.rxlifecycle.ActivityEvent;
import com.trello.rxlifecycle.ActivityLifecycleProvider;
import com.trello.rxlifecycle.RxLifecycle;
import rx.Observable;
import rx.subjects.BehaviorSubject;
/**
* Created by a on 2016/5/6.
*/
public class RxActivity extends FragmentActivity implements ActivityLifecycleProvider {
public final BehaviorSubject lifecycleSubject = BehaviorSubject.create();
@NonNull
@Override
public Observable lifecycle() {
return lifecycleSubject.asObservable();
}
@NonNull
@Override
public Observable.Transformer bindUntilEvent(@NonNull ActivityEvent event) {
return RxLifecycle.bindUntilEvent(lifecycleSubject, event);
}
@NonNull
@Override
public Observable.Transformer bindToLifecycle() {
return RxLifecycle.bindActivity(lifecycleSubject);
}
@Override
@CallSuper
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
lifecycleSubject.onNext(ActivityEvent.CREATE);
}
@Override
@CallSuper
protected void onStart() {
super.onStart();
lifecycleSubject.onNext(ActivityEvent.START);
}
@Override
@CallSuper
protected void onResume() {
super.onResume();
lifecycleSubject.onNext(ActivityEvent.RESUME);
}
@Override
@CallSuper
protected void onPause() {
lifecycleSubject.onNext(ActivityEvent.PAUSE);
super.onPause();
}
@Override
@CallSuper
protected void onStop() {
lifecycleSubject.onNext(ActivityEvent.STOP);
super.onStop();
}
@Override
@CallSuper
protected void onDestroy() {
lifecycleSubject.onNext(ActivityEvent.DESTROY);
super.onDestroy();
}
}
用自己的activity繼承RxActivity.
在聯網請求的地方加上
.compose(RxLifecycle.bindUntilEvent(lifecycle(), ActivityEvent.STOP))
意思是在Stop周期的時候取消請求。
我用了上一篇博客上傳圖片的例子,現在是MainActivity進入SecondActivity之後,點擊按鈕之後上傳一張圖片,然後獲得返回結果。
File file = new File(Environment.getExternalStorageDirectory() + "/123.png");
HttpUtil.getIImagePP().upLoadImage("c1a2b3ab56a2f218aed9b2ab3c16ce88", "be8318b73cef1c2bcafb6c8a77922436", HttpUtil.postFileParams("img", file))
//封裝了在子線程中運行,主線程subscribe,下文會講如何封裝。
.compose(RxHelper.io_main(SecondActivity.this))
//.compose(RxLifecycle.bindUntilEvent(lifecycle(), ActivityEvent.STOP))
.subscribe(new RxSubscriber
沒有加.compose(RxLifecycle.bindUntilEvent(lifecycle(), ActivityEvent.STOP))這一句,點按鈕上傳,然後馬上返回上一個activity的Log日志:
返回到MainActivity之後大概2秒鐘之後,出現了這句
05-06 18:37:58.590 15642-15642/com.sanniuben.myapplication E/way: aaaa
加了之後就沒有返回了。
可見他在onStop的時候取消了這次請求。
RxLifecycle作者的Github
RxFragment源碼頁
Fragment的操作也類似這樣。只不過需要繼承RxFragment
接下來是封裝。
public class RxHelper {
//子線程運行,主線程回調
public static Observable.Transformer io_main(final RxActivity context) {
return new Observable.Transformer() {
@Override
public Observable call(Observable tObservable) {
return (Observable) tObservable
.subscribeOn(Schedulers.io())
.doOnSubscribe(new Action0() {
@Override
public void call() {
//每次請求主線程顯示對話框
ProgressDialogUtil.showProgress(context, "正在加載,請稍候");
}
})
.subscribeOn(AndroidSchedulers.mainThread())
.observeOn(AndroidSchedulers.mainThread())
.compose(RxLifecycle.bindUntilEvent(context.lifecycle(), ActivityEvent.STOP));
}
};
}
}
Subscriber
/**
* Created by a on 2016/5/6.
*/
public abstract class RxSubscriber extends Subscriber{
@Override
public void onCompleted() {
//完成的時候取消對話框
ProgressDialogUtil.dismiss();
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
_onError(e.getMessage());
if (!NetUtils.isConnected(MyApplication.getContextObject())) {
Toast.makeText(MyApplication.getContextObject(), "請求失敗,請檢查網絡!", Toast.LENGTH_SHORT).show();
ProgressDialogUtil.dismiss();;
return;
}
}
@Override
public void onNext(T t) {
_onNext(t);
}
public abstract void _onNext(T t);
public abstract void _onError(String msg);
}
現在來看一下,新的請求
File file = new File(Environment.getExternalStorageDirectory() + "/123.png");
HttpUtil.getIImagePP().upLoadImage("c1a2b3ab56a2f218aed9b2ab3c16ce88", "be8318b73cef1c2bcafb6c8a77922436", HttpUtil.postFileParams("img", file))
//只需要加上這一句
.compose(RxHelper.io_main(SecondActivity.this))
//這裡是new的我們自己的RxSubscriber
.subscribe(new RxSubscriber
這樣就完成了rxjava的封裝。現在實現了每次訪問網絡的時候顯示對話框,請求完取消對話框,在Activity生命周期Stop的時候取消請求。
關於如何實現了rxJava的封裝,去百度或者Google,搜一下rxJava的操作符compose就能明白了。
View布局告一段落,從本篇開始View事件相關分析,今天分析的是View的事件分發機制(PS:本篇文章中源碼均是android 6.0,請知曉)View 事件的分發機制
最近項目裡要做一個簡單的曲線圖來標識數據,開始以為很簡單,android已經有那麼多的開源圖表庫了,什麼achartenginee,hellochart,mpandroi
寫在開頭:已經研究生畢業快一年半了,一直在一家游戲公司做客戶端研發。至於這篇文章講的卻是服務端的東西,主要是因為以前一直沒想寫博客,學到的東西也一直記在本子上就得了。本人
藍牙無法正常工作也是Android 5.0當中常出現的一個問題。有的用戶無法配對,有的在建立連接之後依然無法正常工作,還有的會自動斷開連接。An