Android SDK 26 以下如何使用 AutoDispose 來解決Rxjava 洩露問題

A小白發表於2018-10-15

現在國內大多數使用Rxjava的開發者對於生命週期的管控大部分才用的是Rxlifecycle

但是Rxlifecycle作者的發表卻一篇了名為什麼不是RxLifecycle?

大體上聽出來作者想推薦我們使用uber的AutoDispose去解決這個問題

國內看搜尋的引擎提供的資訊大多數的英文一位名為卻把清梅嗅 的作者釋出的文章這的英文他的github上同時感謝他給予我的幫助!

AutoDispose github中提供的例子是基於最新API的所以在使用的時候他們可以使用Activity的這個

myObservable
    .doStuff()
    .as(autoDisposable(AndroidLifecycleScopeProvider.from(this)))   // The magic
    .subscribe(s -> ...);
複製程式碼

官方提示描述 as 這段程式碼 為魔法程式碼
我們通過檢視原始碼得知autoDisposable()需要的是 LifecycleScopeProvider<?> provider
而AndroidLifecycleScopeProvider.from(this)需要的是LifecycleOwner 介面
from 返回的型別是AndroidLifecycleScopeProvider他實現了介面LifecycleScopeProvider
from 是個轉換器 將 this lifeCycleOwner 轉為了 LifecycleScopeProvider 交給AutoDispose
autoDisposable 也相當於一個轉換器,將LifecycleScopeProvider 轉為 AutoDisposeConverter 並且
實現了 ObservableConverter 可以交由 as 操作符處理。(勿噴,Rxjava原理未看)
總結來說就是 需要Activity 實現LifecyclerOwner 然後就可以一行程式碼將Rxjava 惱人的生命週期繫結在當前Activity上。
但是!API 26 以下官方可沒有實現這個
在API26以及以上版本中我們很容易的就完成了使用直接傳入這即可。
因為AppCompatActivity已經實現了 LifecycleOwner 介面
這裡說的不太準確確切來說是 AppCompatActivity 繼承的活動實現了這個介面我們追到源頭髮現是 SupportActivity
實現了LifecycleOwner 介面所以我們就可以直接使用這個了。
迴歸原題如何在APi 26一下使用呢,當然是我們自己實現一套這樣的邏輯了。
首先將我們的BaseActivity實現LifecycleOwner 介面

  private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);

    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        mLifecycleRegistry.markState(Lifecycle.State.CREATED);
        super.onSaveInstanceState(outState);
    }
複製程式碼

然後建立一個名為ReportFragmentIO的類內容如下 其實可以隨便起看君心情

public class ReportFragmentIO extends Fragment {
    private static final String REPORT_FRAGMENT_TAG = "report_fragment_tag";

    public static void injectIfNeededIn(Activity activity) {
        // ProcessLifecycleOwner應始終正常工作,某些活動可能無法擴充套件
        // 來自支援lib的FragmentActivity,因此我們使用框架片段進行活動
        android.app.FragmentManager manager = activity.getFragmentManager();
        if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
            manager.beginTransaction().add(new ReportFragmentIO(), REPORT_FRAGMENT_TAG).commit();
            //希望我們是第一個進行交易的人.   鬼知道之前是什麼註釋了被百度翻譯了下 
            manager.executePendingTransactions();
        }
    }

    static android.arch.lifecycle.ReportFragment get(Activity activity) {
        return (android.arch.lifecycle.ReportFragment) activity.getFragmentManager().findFragmentByTag(
                REPORT_FRAGMENT_TAG);
    }

    private ActivityInitializationListener mProcessListener;

    private void dispatchCreate(ActivityInitializationListener listener) {
        if (listener != null) {
            listener.onCreate();
        }
    }

    private void dispatchStart(ActivityInitializationListener listener) {
        if (listener != null) {
            listener.onStart();
        }
    }

    private void dispatchResume(ActivityInitializationListener listener) {
        if (listener != null) {
            listener.onResume();
        }
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        dispatchCreate(mProcessListener);
        dispatch(Lifecycle.Event.ON_CREATE);
    }


    @Override
    public void onStart() {
        super.onStart();
        dispatchStart(mProcessListener);
        dispatch(Lifecycle.Event.ON_START);
    }

    @Override
    public void onResume() {
        super.onResume();
        dispatchResume(mProcessListener);
        dispatch(Lifecycle.Event.ON_RESUME);
    }

    @Override
    public void onPause() {
        super.onPause();
        dispatch(Lifecycle.Event.ON_PAUSE);
    }

    @Override
    public void onStop() {
        super.onStop();
        dispatch(Lifecycle.Event.ON_STOP);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        dispatch(Lifecycle.Event.ON_DESTROY);
        //只是想確保我們不會洩漏對Activity的引用
        mProcessListener = null;
    }

    private void dispatch(Lifecycle.Event event) {
        Activity activity = getActivity();
        if (activity instanceof LifecycleRegistryOwner) {
            ((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
            return;
        }

        if (activity instanceof LifecycleOwner) {
            Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
            if (lifecycle instanceof LifecycleRegistry) {
                ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
            }
        }
    }

    void setProcessListener(ActivityInitializationListener processListener) {
        mProcessListener = processListener;
    }

    interface ActivityInitializationListener {
        void onCreate();

        void onStart();

        void onResume();
    }

}

複製程式碼

然後再在我們的BaseActivity的的onCreate中新增一行

ReportFragmentIO.injectIfNeededIn(this);

至此我們就可以在任何繼承我們的BaseActivity的活動中如同API26中一樣使用了

因為我們的專案中大多數用的是MVP架構所以網路請求一般都會在P裡面進行請求

所以接下來會考慮在P中進行繫結生命週期! (存稿並非近日撰寫)

相關文章