RxAndroid之app的生命週期管理RxLifecycle
阿新 • • 發佈:2019-01-07
管理Activity(Fragment、dialogFragment)的生命週期需要在build.gradle中加入compile 'com.trello:rxlifecycle-components:0.6.1'
在Activity或者Fragment中管理Observable的生命週期是很有必要的,未完成的訂閱會引起記憶體洩漏
你必須提供一個Observable<ActivityEvent>或者是Observable<FragmentEvent>來告訴RxLifecycle你需要停止序列發射的時間
你可以通過下面的方式顯式停止序列:
你也可以讓RxLifecycle決定在何時的時間停止序列的傳送myObservable .compose(RxLifecycle.bindUntilEvent(lifecycle, ActivityEvent.DESTROY)) .subscribe();
myObservable
.compose(RxLifecycle.bindActivity(lifecycle))
.subscribe();
//發射的內容,每1s發射一條資料 Observable.interval(1, TimeUnit.SECONDS) //序列停止發射後執行的方法 .doOnUnsubscribe(new Action0() { @Override public void call() { Log.e(TAG, "Unsubscribing subscription from onCreate()"); } }) //指定在哪個生命週期<span style="font-family: Arial, Helvetica, sans-serif;">序列停止發射</span> .compose(this.<Long>bindUntilEvent(ActivityEvent.PAUSE)) //訂閱subscriber .subscribe(new Action1<Long>() { @Override public void call(Long num) { Log.e(TAG, "Started in onCreate(), running until onPause(): " + num); } });
1.指定在某個宣告週期結束
compose(this.<Long>bindUntilEvent(ActivityEvent.PAUSE))
2.使用RxActivity或者RxFragment預設的宣告週期管理來管理
compose(this.<Long>bindToLifecycle())
注:RxActivity、RxFragment中預設的取消訂閱的時間
//RxActivity中的預設LifeCycle // Figures out which corresponding next lifecycle event in which to unsubscribe, for Activities private static final Func1<ActivityEvent, ActivityEvent> ACTIVITY_LIFECYCLE = new Func1<ActivityEvent, ActivityEvent>() { @Override public ActivityEvent call(ActivityEvent lastEvent) { switch (lastEvent) { case CREATE: //如果在onCreate中訂閱,則在onDestroy中序列被停止發射 return ActivityEvent.DESTROY; case START: //如果在onStart中訂閱,則在onStop中<span style="font-family: Arial, Helvetica, sans-serif;">序列被停止發射</span> return ActivityEvent.STOP; case RESUME: //如果在onResume中訂閱,則在onPause中<span style="font-family: Arial, Helvetica, sans-serif;">序列被停止發射</span> return ActivityEvent.PAUSE; case PAUSE: //如果在onPause中訂閱,則在onStop中<span style="font-family: Arial, Helvetica, sans-serif;">序列被停止發射</span> return ActivityEvent.STOP; case STOP: //如果在onStop中訂閱,則在onDestroy中<span style="font-family: Arial, Helvetica, sans-serif;">序列被停止發射</span> return ActivityEvent.DESTROY; case DESTROY: //如果在onDestroy中訂閱,則丟擲異常 throw new OutsideLifecycleException("Cannot bind to Activity lifecycle when outside of it."); default: throw new UnsupportedOperationException("Binding to " + lastEvent + " not yet implemented"); } } }; //RxFragment中的預設LifeCycle // Figures out which corresponding next lifecycle event in which to unsubscribe, for Fragments private static final Func1<FragmentEvent, FragmentEvent> FRAGMENT_LIFECYCLE = new Func1<FragmentEvent, FragmentEvent>() { @Override public FragmentEvent call(FragmentEvent lastEvent) { switch (lastEvent) { case ATTACH: //如果在onAttach中訂閱,則在onDetach中<span style="font-family: Arial, Helvetica, sans-serif;">序列被停止發射</span> return FragmentEvent.DETACH; case CREATE: //如果在onCreate中訂閱,則在onDestroy中<span style="font-family: Arial, Helvetica, sans-serif;">序列被停止發射</span> return FragmentEvent.DESTROY; case CREATE_VIEW: //如果在onCreateView中訂閱,則在onDestroyView中<span style="font-family: Arial, Helvetica, sans-serif;">序列被停止發射</span> return FragmentEvent.DESTROY_VIEW; case START: //如果在onStart中訂閱,則在onStop中<span style="font-family: Arial, Helvetica, sans-serif;">序列被停止發射</span> return FragmentEvent.STOP; case RESUME: //如果在onResume中訂閱,則在onPause中<span style="font-family: Arial, Helvetica, sans-serif;">序列被停止發射</span> return FragmentEvent.PAUSE; case PAUSE: //如果在onPause中訂閱,則在onStop中<span style="font-family: Arial, Helvetica, sans-serif;">序列被停止發射</span> return FragmentEvent.STOP; case STOP: //如果在onStop中訂閱,則在onDestroy中<span style="font-family: Arial, Helvetica, sans-serif;">序列被停止發射</span> return FragmentEvent.DESTROY_VIEW; case DESTROY_VIEW: //如果在onDestroyView中訂閱,則在onDestroyView中<span style="font-family: Arial, Helvetica, sans-serif;">序列被停止發射</span> return FragmentEvent.DESTROY; case DESTROY: //如果在onDestroyView中訂閱,則在onDestroyView中<span style="font-family: Arial, Helvetica, sans-serif;">序列被停止發射</span> return FragmentEvent.DETACH; case DETACH: //如果在onDetach中訂閱,則丟擲異常 throw new OutsideLifecycleException("Cannot bind to Fragment lifecycle when outside of it."); default: throw new UnsupportedOperationException("Binding to " + lastEvent + " not yet implemented"); } } };
測試程式碼:
public class RxLifecycleActivity extends RxAppCompatActivity{
private static final String TAG = "RxLifecycle";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.e(TAG, "onCreate()");
// Specifically bind this until onPause()
//發射的內容,每1s發射一條資料
Observable.interval(1, TimeUnit.SECONDS)
//<span style="font-family: Arial, Helvetica, sans-serif;">序列被停止發射</span><span style="font-family: Arial, Helvetica, sans-serif;">後執行的方法</span>
.doOnUnsubscribe(new Action0() {
@Override
public void call() {
Log.e(TAG, "Unsubscribing subscription from onCreate()");
}
})
//指定在哪個生命週期,在onPause()中<span style="font-family: Arial, Helvetica, sans-serif;">序列被停止發射</span>
.compose(this.<Long>bindUntilEvent(ActivityEvent.PAUSE))
//訂閱subscriber
.subscribe(new Action1<Long>() {
@Override
public void call(Long num) {
Log.e(TAG, "Started in onCreate(), running until onPause(): " + num);
}
});
}
@Override
protected void onStart() {
super.onStart();
Log.e(TAG, "onStart()");
// Using automatic unsubscription, this should determine that the correct time to
// unsubscribe is onStop (the opposite of onStart).
Observable.interval(1, TimeUnit.SECONDS)
.doOnUnsubscribe(new Action0() {
@Override
public void call() {
Log.e(TAG, "Unsubscribing subscription from onStart()");
}
})
//使用預設的宣告週期取消訂閱,在RxActivity中,如果在onStart中訂閱,則在onStop中<span style="font-family: Arial, Helvetica, sans-serif;">序列被停止發射</span>
.compose(this.<Long>bindToLifecycle())
.subscribe(new Action1<Long>() {
@Override
public void call(Long num) {
Log.e(TAG, "Started in onStart(), running until in onStop(): " + num);
}
});
}
@Override
protected void onResume() {
super.onResume();
Log.e(TAG, "onResume()");
// `this.<Long>` is necessary if you're compiling on JDK7 or below.
//
// If you're using JDK8+, then you can safely remove it.
Observable.interval(1, TimeUnit.SECONDS)
.doOnUnsubscribe(new Action0() {
@Override
public void call() {
Log.e(TAG, "Unsubscribing subscription from onResume()");
}
})
//指定在onDestroy()中<span style="font-family: Arial, Helvetica, sans-serif;">序列被停止發射</span>
.compose(this.<Long>bindUntilEvent(ActivityEvent.DESTROY))
.subscribe(new Action1<Long>() {
@Override
public void call(Long num) {
Log.e(TAG, "Started in onResume(), running until in onDestroy(): " + num);
}
});
}
@Override
protected void onPause() {
super.onPause();
Log.e(TAG, "onPause()");
}
@Override
protected void onStop() {
super.onStop();
Log.e(TAG, "onStop()");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.e(TAG, "onDestroy()");
}
執行結果:
注:1.參考資料https://github.com/trello/RxLifecycle
2.RxLifecycle不會自動取消訂閱,他只是停止了序列繼續發射,取消訂閱需要手動執行