【RxJava Demo分析】(二)Schedulers线程调度器

来源:互联网 发布:华为mate9下载软件 编辑:程序博客网 时间:2024/06/06 03:38

ConcurrencyWithSchedulersDemoFragment

用Schedulers(调度器)实现多任务(并发,Concurrency)的例子

废话不多说我们看一下有关于RxJava的代码:

    private Subscription _subscription;    @OnClick(R.id.btn_start_operation) //    public void startLongOperation() {        _progress.setVisibility(View.VISIBLE);        _log("Button Clicked");        _subscription = _getObservable()//                .subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(_getObserver());                             // Observer    }    private Observable<Boolean> _getObservable() {        return Observable.just(true).map(new Func1<Boolean, Boolean>() {            @Override            public Boolean call(Boolean aBoolean) {                _log("Within Observable");                _doSomeLongOperation_thatBlocksCurrentThread();//长时间的操作,阻塞线程                return aBoolean;            }        });    }    private Observer<Boolean> _getObserver() {        return new Observer<Boolean>() {            //....一些操作        };    }

这段代码比较简单,只涉及了一个知识点Schedulers调度器

Schedulers

概括:线程调度器,用来达到切换线程的效果。

在Android开发中,由于UI线程是不能够被阻塞的,不然就会产生ANR导致程序崩溃。所以我们经常的处理是,两种方法:

1.新开线程(或者线程池中)处理阻塞的操作:

        new Thread(new Runnable() {            @Override            public void run() {                try{                    mEntity = getEntity();                    mHandler.obtainMessage(1,mEntity).sendToTarget();                }catch (Exception e){                    mHandler.sendEmptyMessage(0);                }            }        }).start();

大家可以看到,我们这里只是进行了一个简单的IO操作,就陷入了这么谜一般的缩进。要是设计更加复杂的呢?

而且我们还要用Handler处理消息,造成了编码的撕裂感! 虽然我个人对Handler并不反感,但在编码的时候,它的存在的确让我感到有点惆怅~~

2.回调处理

        HttpClient.getInstance().get("http://www.qq.com",new HttpCallback(){            public void onSuccess(String result){                //...成功操作            }            public void onError(Exception e){                //...失败操作            }        });

这里我们随便写了一个获取QQ主页的首页数据的操作。 虽然现在看起来还是蛮简单的。 只有一层回调,但是要是我们要针对QQ返回的结果,再进行一次热门词汇的搜索文章,搜索出来的文章我还要获取第五篇文章,然后我再获取第五篇文章的评论呢?

这里就会陷入Callback Hell (回调地狱)! 维护起来真的是太恶心了!

3.小结一下Schedulers

Schedulers调度器的出现,保持了我们使用RxJava的链式调用,不会出现撕裂感,因为它可以帮我们游刃有余的进行线程切换,而不需要进行Hanlder或者回调!

也正是Schedulers的出现才让我下定决心学习RxJava的初衷! 这实在的太棒了(当然还有无穷无尽的操作符~~)

结束

1.关于Schedulers的原理

因为能力还没有到这里层度,毕竟RxJava和一般的库不一样,它里面涉及了很多“高端知识”而我也不敢乱说出来误导。 所以呢~这里附上前辈的分析吧(反正我看的是有点一头雾水):给 Android 开发者的 RxJava 详解 里面有一部分是涉及Schedulers分析的。

我觉得要是看不懂也没关系,随着我们使用的越来越多,没准在哪一天心血来潮想看看源码的时候突然就明白了呢~

在未来的学习,要是我突然明白了,我会尽快写一篇文章和大家讨论的~

2.附录:完整源代码

public class ConcurrencyWithSchedulersDemoFragment        extends BaseFragment {    @Bind(R.id.progress_operation_running)    ProgressBar _progress;    @Bind(R.id.list_threading_log)    ListView _logsList;    private LogAdapter _adapter;    private List<String> _logs;    private Subscription _subscription;    @Override    public void onDestroy() {        super.onDestroy();        RxUtils.unsubscribeIfNotNull(_subscription);        ButterKnife.unbind(this);    }    @Override    public void onActivityCreated(@Nullable Bundle savedInstanceState) {        super.onActivityCreated(savedInstanceState);        _setupLogger();    }    @Override    public View onCreateView(LayoutInflater inflater,                             @Nullable ViewGroup container,                             @Nullable Bundle savedInstanceState) {        View layout = inflater.inflate(R.layout.fragment_concurrency_schedulers, container, false);        ButterKnife.bind(this, layout);        return layout;    }    @OnClick(R.id.btn_start_operation)    public void startLongOperation() {        _progress.setVisibility(View.VISIBLE);        _log("Button Clicked");        _subscription = _getObservable()//                .subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(_getObserver());                             // Observer    }    private Observable<Boolean> _getObservable() {        return Observable.just(true).map(new Func1<Boolean, Boolean>() {            @Override            public Boolean call(Boolean aBoolean) {                _log("Within Observable");                _doSomeLongOperation_thatBlocksCurrentThread();                return aBoolean;            }        });    }    /**     * Observer that handles the result through the 3 important actions:     * <p/>     * 1. onCompleted     * 2. onError     * 3. onNext     */    private Observer<Boolean> _getObserver() {        return new Observer<Boolean>() {            @Override            public void onCompleted() {                _log("On complete");                _progress.setVisibility(View.INVISIBLE);            }            @Override            public void onError(Throwable e) {                Timber.e(e, "Error in RxJava Demo concurrency");                _log(String.format("Boo! Error %s", e.getMessage()));                _progress.setVisibility(View.INVISIBLE);            }            @Override            public void onNext(Boolean bool) {                _log(String.format("onNext with return value \"%b\"", bool));            }        };    }    // -----------------------------------------------------------------------------------    // Method that help wiring up the example (irrelevant to RxJava)    private void _doSomeLongOperation_thatBlocksCurrentThread() {        _log("performing long operation");        try {            Thread.sleep(3000);        } catch (InterruptedException e) {            Timber.d("Operation was interrupted");        }    }    private void _log(String logMsg) {        if (_isCurrentlyOnMainThread()) {            _logs.add(0, logMsg + " (main thread) ");            _adapter.clear();            _adapter.addAll(_logs);        } else {            _logs.add(0, logMsg + " (NOT main thread) ");            // You can only do below stuff on main thread.            new Handler(Looper.getMainLooper()).post(new Runnable() {                @Override                public void run() {                    _adapter.clear();                    _adapter.addAll(_logs);                }            });        }    }    private void _setupLogger() {        _logs = new ArrayList<String>();        _adapter = new LogAdapter(getActivity(), new ArrayList<String>());        _logsList.setAdapter(_adapter);    }    private boolean _isCurrentlyOnMainThread() {        return Looper.myLooper() == Looper.getMainLooper();    }    private class LogAdapter            extends ArrayAdapter<String> {        public LogAdapter(Context context, List<String> logs) {            super(context, R.layout.item_log, R.id.item_log, logs);        }    }}

-Hans 2016.3.5 13:36

0 0
原创粉丝点击