日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

Android rxjava2的disposable

發(fā)布時間:2023/12/19 综合教程 28 生活家
生活随笔 收集整理的這篇文章主要介紹了 Android rxjava2的disposable 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

rxjava+retrofit處理網(wǎng)絡(luò)請求

在使用rxjava+retrofit處理網(wǎng)絡(luò)請求的時候,一般會采用對觀察者進(jìn)行封裝,實現(xiàn)代碼復(fù)用和拓展。可以參考我的這篇文章:rxjava2+retrofit封裝處理網(wǎng)絡(luò)請求全解析。一種可行的封裝如下:

基類observer

public abstract class BaseObserver<T> implements Observer<T> {

    protected String errMsg = "";
    protected Disposable disposable;

    @Override
    public void onSubscribe(Disposable d) {
        disposable = d;
    }

    @Override
    public void onNext(T t) {}

    @Override
    public void onError(Throwable e) {
        LogUtils.d("Subscriber onError", e.getMessage());
        if (!NetworkUtils.isConnected()) {
            errMsg = "網(wǎng)絡(luò)連接出錯,";
        } else if (e instanceof APIException) {
            APIException exception = (APIException) e;
            errMsg = exception.getMessage() + ", ";
        } else if (e instanceof HttpException) {
            errMsg = "網(wǎng)絡(luò)請求出錯,";
        } else if (e instanceof IOException) {
            errMsg = "網(wǎng)絡(luò)出錯,";
        }

        if (disposable != null && !disposable.isDisposed()) {
            disposable.dispose();
        }
    }

    @Override
    public void onComplete() {
        if (disposable != null && !disposable.isDisposed()) {
            disposable.dispose();
        }
    }
}

封裝請求(登錄為例) 這里userService是retrofit接口類

 public void login(String phone, String password, BaseObserver<ResponseBean<UidBean>> observer) {
        userService.login(phone,password)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
    }

方法調(diào)用

APIUser.getInstance().login(phone, password, new BaseObserver<ResponseBean<UidBean>>() {
             @Override
             public void onNext(ResponseBean<UidBean> responseBean) {
                ToastUtils.showShort("登錄成功");
             }
         });

關(guān)于rxjava和retrofit的詳細(xì)封裝,可以看我的這篇文章:rxjava2+retrofit封裝處理網(wǎng)絡(luò)請求全解析。

關(guān)于disposable

rxjava雖然好用,但是總所周知,容易遭層內(nèi)存泄漏。也就說在訂閱了事件后沒有及時取閱,導(dǎo)致在activity或者fragment銷毀后仍然占用著內(nèi)存,無法釋放。而disposable便是這個訂閱事件,可以用來取消訂閱。但是在什么時候取消訂閱呢?我知道有兩種方式:

使用CompositeDisposable

看源碼,CompositeDisposable的介紹很簡單

A disposable container that can hold onto multiple other disposables and offers O(1) add and removal complexity.

一個disposable的容器,可以容納多個disposable,添加和去除的復(fù)雜度為O(1)。
這里需要注意的是在該類的addAll方法有這么一句注釋

Atomically adds the given array of Disposables to the container or disposes them all if the container has been disposed

也就是說,如果這個CompositeDisposable容器已經(jīng)是處于dispose的狀態(tài),那么所有加進(jìn)來的disposable都會被自動切斷。

所以說可以創(chuàng)建一個BaseActivity,用CompositeDisposable來管理訂閱事件disposable,然后在acivity銷毀的時候,調(diào)用compositeDisposable.dispose()就可以切斷所有訂閱事件,防止內(nèi)存泄漏。

在oError和onComplete后調(diào)用disposable.dispose();,也就是上面我給的例子中的方法。

查看源碼,ObservableCreate的靜態(tài)類CreateEmitter就是這種方式實現(xiàn)的。同時也可以看到,onError和onComplete不可以同時調(diào)用的原因:每次掉用過onError或onComplete其中一個方法后,就會掉用dispose()方法,此時訂閱取消,自然也就不能掉用另一個方法了

static final class CreateEmitter<T> 
implements ObservableEmitter<T>, Disposable {

    private static final long serialVersionUID = -3434801548987643227L;

    final Observer<? super T> observer;

    CreateEmitter(Observer<? super T> observer) {
        this.observer = observer;
    }

    @Override
    public void onNext(T t) {
        if (t == null) {
            onError(new NullPointerException("onNext called with null. Null values are generally not allowed in 2.x operators and sources."));
            return;
        }
        if (!isDisposed()) {
            observer.onNext(t);
        }
    }

    @Override
    public void onError(Throwable t) {
        if (t == null) {
            t = new NullPointerException("onError called with null. Null values are generally not allowed in 2.x operators and sources.");
        }
        if (!isDisposed()) {
            try {
                observer.onError(t);
            } finally {
                dispose();
            }
        } else {
            RxJavaPlugins.onError(t);
        }
    }

    @Override
    public void onComplete() {
        if (!isDisposed()) {
            try {
                observer.onComplete();
            } finally {
                dispose();
            }
        }
    }

    @Override
    public void setDisposable(Disposable d) {
        DisposableHelper.set(this, d);
    }

    @Override
    public void setCancellable(Cancellable c) {
        setDisposable(new CancellableDisposable(c));
    }

    @Override
    public ObservableEmitter<T> serialize() {
        return new SerializedEmitter<T>(this);
    }

    @Override
    public void dispose() {
        DisposableHelper.dispose(this);
    }

    @Override
    public boolean isDisposed() {
        return DisposableHelper.isDisposed(get());
    }
}

除此之外,在github發(fā)現(xiàn)一個開源庫RxLifecyclee,粗略了解發(fā)現(xiàn)他實現(xiàn)的原理是綁定acvitvity是生命周期,在onStart中綁定就在onStop中解綁,其他onResume,onCreate同理。這個和第一種方式似乎又差不多,只不過第一種方式簡單,只在ondestory的時候銷毀所有事件。

總結(jié)

以上是生活随笔為你收集整理的Android rxjava2的disposable的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。