Android 性能優化之利用 Rxlifecycle 解決 RxJava 內存泄漏

前言:

其實RxJava引起的內存泄漏是我無意中發現了,本來是想了解Retrofit與RxJava相結合中是如何通過適配器模式解決的,結果卻發現了RxJava是會引起內存泄漏的,所有想著查找一下資料學習一下如何解決RxJava引起的內存泄漏,就查到了利用Rxlifecycle開源框架可以解決,今天周末就來學習一下如何使用Rxlifecycle。

引用泄漏的背景:

RxJava作為一種響應式編程框架,是目前編程界網紅,可謂是家喻戶曉,其簡潔的編碼風格、易用易讀的鏈式方法調用、強大的異步支持等使得RxJava被廣泛使用,它通過線程調度器更容易控制和切換線程,如果該工作線程還沒執行結束就退出Activity或者Fragment,就會Activity或者Fragment無法釋放引起內存泄漏。

什么是Rxlifecycle?

rxlifecycle是trello開發的用于解決RxJava引起的內存泄漏的開源框架。

如何使用Rxlifecycle?

1.)在build.gradle文件中添加引用

compile 'com.trello:rxlifecycle:1.0'

// If you want to bind to Android-specific lifecycles compile 'com.trello:rxlifecycle-android:1.0'

// If you want pre-written Activities and Fragments you can subclass as providers compile 'com.trello:rxlifecycle-components:1.0'

// If you want to use Navi for providers compile 'com.trello:rxlifecycle-navi:1.0'

// If you want to use Kotlin syntax compile 'com.trello:rxlifecycle-kotlin:1.0' </code></pre>

根據自己的需要添加 我這里使用了如下兩個

 compile 'com.trello:rxlifecycle:1.0'
 compile 'com.trello:rxlifecycle-components:1.0'

2.)根據不同的需要Activity繼承RxActivity ,Fragment繼承RxFragment

public class MainActivity7 extends RxActivity {
    private TextView mTextView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mTextView = (TextView) findViewById(R.id.text);
    //模擬內存泄露
    testRxJava();
    finish();
}

private void testRxJava() {
    Observable.create(new Observable.OnSubscribe<String>() {
        @Override
        public void call(Subscriber<? super String> subscriber) {
            int i = 0;
            while (i < 1000000000) {
                i++;
            }
            subscriber.onNext(String.valueOf(i));
            subscriber.onCompleted();
        }
    }).compose(this.<String>bindUntilEvent(ActivityEvent.PAUSE))
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Action1<String>() {
                @Override
                public void call(String s) {
                    mTextView.setText(s);
                }
            });

}


@Override
protected void onDestroy() {
    super.onDestroy();
    LApplication.getRefWatcher().watch(this);
}

} </code></pre>

目前支持的Activity/Fragment 結構圖

3.)使用bindToLifecycle()的方式

在子類使用Observable中的compose操作符,調用,完成Observable發布的事件和當前的組件綁定,實現生命周期同步。從而實現當前組件生命周期結束時,自動取消對Observable訂閱。

 Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                int i = 0;
                while (i < 1000000000) {
                    i++;
                }
                subscriber.onNext(String.valueOf(i));
                subscriber.onCompleted();
            }
        }).compose(this.<String>bindToLifecycle())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        mTextView.setText(s);
                    }
                });

4.)使用bindUntilEvent()方式

使用ActivityEvent類,其中的CREATE、START、 RESUME、PAUSE、STOP、 DESTROY分別對應生命周期內的方法。使用bindUntilEvent指定在哪個生命周期方法調用時取消訂閱。

      Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                int i = 0;
                while (i < 1000000000) {
                    i++;
                }
                subscriber.onNext(String.valueOf(i));
                subscriber.onCompleted();
            }
        }).compose(this.<String>bindUntilEvent(ActivityEvent.PAUSE))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        mTextView.setText(s);
                    }
                });

5.)自定義一個RxActivity/RxFragment

只需要你想要的Activity實現LifecycleProvider<ActivityEvent>接口就可以了,這里貼出RxActivity的源碼仿照它做下修改即可。

public abstract class RxActivity extends Activity implements LifecycleProvider<ActivityEvent> {
    private final BehaviorSubject<ActivityEvent> lifecycleSubject = BehaviorSubject.create();

public RxActivity() {
}

@NonNull
@CheckResult
public final Observable<ActivityEvent> lifecycle() {
    return this.lifecycleSubject.asObservable();
}

@NonNull
@CheckResult
public final <T> LifecycleTransformer<T> bindUntilEvent(@NonNull ActivityEvent event) {
    return RxLifecycle.bindUntilEvent(this.lifecycleSubject, event);
}

@NonNull
@CheckResult
public final <T> LifecycleTransformer<T> bindToLifecycle() {
    return RxLifecycleAndroid.bindActivity(this.lifecycleSubject);
}

@CallSuper
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.lifecycleSubject.onNext(ActivityEvent.CREATE);
}

@CallSuper
protected void onStart() {
    super.onStart();
    this.lifecycleSubject.onNext(ActivityEvent.START);
}

@CallSuper
protected void onResume() {
    super.onResume();
    this.lifecycleSubject.onNext(ActivityEvent.RESUME);
}

@CallSuper
protected void onPause() {
    this.lifecycleSubject.onNext(ActivityEvent.PAUSE);
    super.onPause();
}

@CallSuper
protected void onStop() {
    this.lifecycleSubject.onNext(ActivityEvent.STOP);
    super.onStop();
}

@CallSuper
protected void onDestroy() {
    this.lifecycleSubject.onNext(ActivityEvent.DESTROY);
    super.onDestroy();
}

} </code></pre>

總結:

本文總結了通過RxLifeCycle解決RxJava的內存泄漏問題,同時也給我們提了一個警告,再好的框架都有它好的一面也有壞的一面,這時做好技術選型以及規避風險就很重要了。

 

來自:http://www.cnblogs.com/whoislcj/p/6054167.html

 

 本文由用戶 liuyongly 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!