手记

逻辑连续性和回调地狱

0x00 问题点
  • 复杂逻辑如何保证连续性?
    类似于网络请求和各种持久化操作,由于回调的原因,每一步的代码可能并不是写在同一个地方,如何解决逻辑连续性和代码可维护性?
  • 基于回调的操作如何解决回调地狱问题?
    这和第一个问题是有关联的,如果大量的操作都是基于回调的,那么该如何解决回调地狱(Callback Hell)的问题?
0x01 答案

使用RxJava可以解决上述两个问题。

0x02 举个例子
  • 案例描述
    有这样一个需求,需要先去调用一个接口,从服务器拉取图片地址,然后显示在界面上,显示后将这个图片和此界面上的其他元素一起截图保存,然后调用微信分享出去。
  • 案例分析
    需求并不复杂,但是涉及到了多次线程切换和异步操作,做网络请求需要在线程执行,将图片显示到界面上需要在主线程执行,将界面截图保存需要在线程执行,调用微信分享出去又需要在主线程执行。短短的一个简单的需求,就需要来回几次的线程切换。
  • 不使用RxJava的写法
// 调用接口获取图片地址
NetworkService.execute(request, new Callback() {

            @Override
            public void onSuccess(String url) {
                // 加载图片
                ImageLoader.load(url, new Callback() {

                    @Override
                    public void onSuccess(final Bitmap bitmap) {

                        runOnUiThread(new Runnable() {

                            @Override
                            public void run() {
                                // 设置显示图片
                                tImageView.setImageBitmap(bitmap);
                                new Thread(new Runnable() {

                                    @Override
                                    public void run() {
                                        // 获取当前View的Bitmap
                                        tContentView.setDrawingCacheEnabled(true);
                                        Bitmap tScreenshotBitmap = tContentView.getDrawingCache();
                                        // 拷贝图片
                                        final Bitmap tShareBitmap = Bitmap.createBitmap(tScreenshotBitmap);
                                        tContentView.setDrawingCacheEnabled(false);
                                        runOnUiThread(new Runnable() {

                                            @Override
                                            public void run() {
                                                // 微信分享
                                                WeiXinShare.share(tShareBitmap);
                                            }
                                        });
                                    }
                                }).start();
                            }
                        });
                    }
                });
            }
        });

可以看出,如果不使用RxJava,代码中存在多处回调,这还是一个简单的需求,如果需求再复杂一点,回调嵌套的层数多了,这就是回调地狱。还有,我们这里的代码使用的是单一回调处理,每做一个事情写一个单独的回调对象,如果使用的是统一回调处理,或者用Android里的AsyncTask,那么处理后的逻辑,势必要散在各处,难以阅读,逻辑连续性不好。

  • 使用RxJava的写法
Observable.
                        create(new Observable.OnSubscribe<String>() {
                            @Override
                            public void call(Subscriber<? super String> subscriber) {
                                // 调用接口获取图片地址
                                String tUrl = NetworkService.execute(request);
                                if (subscriber.isUnsubscribed()) {
                                    return;
                                }
                                subscriber.onNext(tUrl);
                                subscriber.onCompleted();
                            }
                        }).
                        subscribeOn(Schedulers.io()).
                        map(new Func1<String, Bitmap>() {
                            @Override
                            public Bitmap call(String s) {
                                // 加载图片
                                return ImageLoader.load(s);
                            }
                        }).
                        observeOn(AndroidSchedulers.mainThread()).
                        map(new Func1<Bitmap, Boolean>() {
                            @Override
                            public Boolean call(Bitmap bitmap) {
                                // 显示图片
                                tImageView.setImageBitmap(bitmap);
                                return true;
                            }
                        }).
                        observeOn(Schedulers.io()).
                        map(new Func1<Boolean, Bitmap>() {
                            @Override
                            public Bitmap call(Boolean aBoolean) {
                                // 获取当前View的Bitmap
                                tContentView.setDrawingCacheEnabled(true);
                                Bitmap tScreenshotBitmap = tContentView.getDrawingCache();
                                // 拷贝图片
                                final Bitmap tShareBitmap = Bitmap.createBitmap(tScreenshotBitmap);
                                tContentView.setDrawingCacheEnabled(false);
                                return tShareBitmap;
                            }
                        }).
                        observeOn(AndroidSchedulers.mainThread()).
                        subscribe(new Action1<Bitmap>() {
                            @Override
                            public void call(Bitmap bitmap) {
                                // 微信分享   
                                WeiXinShare.share(bitmap);
                            }
                        });

可以看出,使用了RxJava并不是使代码减少,而且让代码逻辑连续且整洁,杜绝回调地狱,所有的步骤都是在一个代码层级上,没有过多层次的嵌套,这就是RxJava的优点。

但是RxJava是如何实现这一效果的,这就是我们以后要探讨的问题了。

6人推荐
随时随地看视频
慕课网APP

热门评论

rxjava线程调度真的厉害

查看全部评论