android 使用RxJava实现预加载

上一篇文章中介绍了使用非RxJava环境下,使用Handler机制SyncBarrier的特性实现预加载功能的方法。

在RxJava的环境下使用BehaviorSubject的特性来实现也是很方便的。

BehaviorSubject

BehaviorSubject内部会缓存消息流中最近的一个消息, 在后续有Subscriber订阅时,会直接将缓存的消息发送给Subscriber。

RxPreLoader.java封装如下:


import android.support.annotation.NonNull;

import java.util.LinkedList;

import rx.Observable;
import rx.Observer;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
import rx.subjects.BehaviorSubject;

/**
 * 预加载
 * preLoader = RxPreLoader.preLoad(observable);
 * preLoader.get(observer1);
 * preLoader.get(observer2);
 * preLoader.reload();
 * preLoader.destroy()
 *
 * @author billy.qi
 */
public class RxPreLoader<T> {
    private BehaviorSubject<T> subject;
    private Observable<T> observable;
    private Subscription subscription;
    private final LinkedList<Subscription> allObserver = new LinkedList<>();


    private RxPreLoader(Observable<T> observable) {
        //注意的是由于onCompleted也是数据流中的一个
        //如果直接observer.subscribeOn(Schedulers.io()).subscribe(subject);
        //会导致subject只能缓存onCompleted
        //所以此处新建一个OnSubscribe,通过调用subject.onNext(t)的方式来缓存数据
        this.observable = observable;
        subject = BehaviorSubject.create();
        subscription = Observable.create(new Observable.OnSubscribe<T>() {
            @Override
            public void call(Subscriber<? super T> subscriber) {
                performLoad();
            }
        })
        .subscribeOn(Schedulers.io())
        .subscribe(subject);
    }

    public static <R> RxPreLoader<R> preLoad(@NonNull Observable<R> observable) {
        return new RxPreLoader<R>(observable);
    }

    public void reload() {
        performLoad();
    }

    public Subscription get(Observer<T> observer) {
        Subscription subscription = subject.observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
        allObserver.add(subscription);
        return subscription;
    }


    private void performLoad() {
        observable.subscribeOn(Schedulers.io())
                .subscribe(new Action1<T>() {
                    @Override
                    public void call(T t) {
                        if (subject != null) {
                            subject.onNext(t);
                        }
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        throwable.printStackTrace();
                    }
                });
    }

    public void destroy() {
        synchronized (allObserver) {
            while(!allObserver.isEmpty()) {
                unsubscribe(allObserver.removeFirst());
            }
        }
        unsubscribe(subscription);
        subscription = null;
        subject = null;
    }

    private void unsubscribe(Subscription subscription) {
        if (subscription != null && !subscription.isUnsubscribed()) {
            subscription.unsubscribe();
        }
    }
}

在activity中使用:


import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;

import java.util.concurrent.TimeUnit;

import rx.Observable;
import rx.Subscriber;

/**
 * 使用RxJava实现的预加载方式
 */
public class RxPreLoaderActivity extends AppCompatActivity {

    private TextView textView;
    private RxPreLoader<String> preLoader;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        preLoad();//启动预加载
        initLayout(savedInstanceState);
        preLoader.get(observer);//展示预加载的数据
    }

    //初始化布局
    private void initLayout(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setTitle("使用RxPreLoader");
        //通过循环多次findById来模拟复杂页面布局初始化的耗时
        textView = (TextView)findViewById(R.id.textView);
    }

    //展示预加载的数据
    Subscriber<String> observer = new Subscriber<String>() {
        @Override public void onCompleted() { }

        @Override public void onError(Throwable e) {
            e.printStackTrace();
        }

        @Override
        public void onNext(String s) {
            textView.setText(s);
        }
    };

    private void preLoad() {
        preLoader = RxPreLoader.preLoad(Observable.just("result").delay(500, TimeUnit.MILLISECONDS));
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        preLoader.destroy();//销毁
    }
}

原文地址: http://blog.csdn.net/cdecde111/article/details/54670543
最后,附上源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值