RxJava在Android中記憶體流失解決以及RxJava的封裝。

來源:互聯網
上載者:User

標籤:

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<ActivityEvent> lifecycleSubject = BehaviorSubject.create();    @NonNull    @Override    public Observable<ActivityEvent> lifecycle() {        return lifecycleSubject.asObservable();    }    @NonNull    @Override    public <T> Observable.Transformer<T, T> bindUntilEvent(@NonNull ActivityEvent event) {        return RxLifecycle.bindUntilEvent(lifecycleSubject, event);    }    @NonNull    @Override    public <T> Observable.Transformer<T, T> 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<Object>() {                    @Override                    public void _onNext(Object o) {                        L.e("aaaa");                        tv.setText((String) o);                    }                    @Override                    public void _onError(String msg) {                    }                });

沒有加.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 <T> Observable.Transformer<T, T> io_main(final RxActivity context) {        return new Observable.Transformer<T, T>() {            @Override            public Observable<T> call(Observable<T> tObservable) {                return (Observable<T>) 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<T> extends Subscriber<T>{    @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<Object>() {                    @Override                    public void _onNext(Object o) {                        L.e("aaaa");                        tv.setText((String) o);                    }                    @Override                    public void _onError(String msg) {                    }                });

這樣就完成了rxjava的封裝。現在實現了每次訪問網路的時候顯示對話方塊,請求完取消對話方塊,在Activity生命週期Stop的時候取消請求。
關於如何?了rxJava的封裝,去百度或者Google,搜一下rxJava的操作符compose就能明白了。

下班了,來不及解釋太多了,如果看的人多,有時間再來更新細節。

項目demo地址(嫌麻煩沒有分離模組,直接把項目未搭建完的架構放上來了):
Demo在上傳,等會回去更新

RxJava在Android中記憶體流失解決以及RxJava的封裝。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.