美文网首页
ARouter源码分析-降级策略

ARouter源码分析-降级策略

作者: dashingqi | 来源:发表于2020-07-25 12:34 被阅读0次
Android_Banner.jpg

简介

  • 通常我们进行页面跳转的时候,调用startActivity()之后我们就无法控制了,之后出现什么问题或者异常,我们都把控不好,有时候针对用户来说就是一个闪退,这样用户体验很不好
  • 但是ARouter给我们提供的这个降级策略,便能很友好的避免这个问题,当进行页面跳转出现问题的时候,我们可以通过降级策略去加载一个H5页面或者跳转到一个提醒页面,这样对用户来说体验就非常好了

降级策略的使用

  • ARouter中为我们提供了单独降级和全局降级
  • 这两种降级不能同时使用,如果同时使用那么单独降级会将全局降级进行覆盖了,不会执行全局降级的逻辑了
单独降级 --- 接口
  • 测试代码
 mBtnDegrade.setOnClickListener(view->{
            ARouter.getInstance().build("/test/test").navigation(this, new NavigationCallback() {
                @Override
                public void onFound(Postcard postcard) {
                    Log.d(TAG, "onFound: 找到了");

                }

                /**
                 * 出现问题会回调该方法
                 * 也就是我们降级策略的处理回调
                 * @param postcard
                 */
                @Override
                public void onLost(Postcard postcard) {
                    Log.d(TAG, "onLost: 没有找到哟");

                }

                @Override
                public void onArrival(Postcard postcard) {
                    Log.d(TAG, "onArrival: 跳转完事了");

                }

                @Override
                public void onInterrupt(Postcard postcard) {
                    Log.d(TAG, "onInterrupt: 被拦截了");

                }
            });

        });
// 在本例子中,我们的路由地址 ("/test/test")是一个不存在的页面,
// 观察打印的log我们可以看出来回调到了 onLost方法
// 这就是单独降级策略达到的效果,我们可以在 onLost方法中做一些逻辑
//说完了单独降级我们看下全局降级吧
全局降级 --- 服务接口的形式(Provider)
  • 全局降级就是我们需要实现ARouter提供的DegradeService接口(DegradeServie extends IProvider)是Provider类型的
  • DegradeService接口内就只有一个方法 onLost() 如果在页面跳转出现任何问题,都会回调到onLost方法中
  • 代码测试
// 声明一个降级策略服务类 实现了 DegradeService
// 使用注解Route 标识这个 Provider类型
@Route(path = "/degrade/test")
public class MyDegradeService implements DegradeService {

    private static final String TAG = "MyDegradeService";
    @Override
    public void onLost(Context context, Postcard postcard) {
        Log.d(TAG, "onLost: ");

    }

    @Override
    public void init(Context context) {
        Log.d(TAG, "init: ");

    }
}

//点击按钮进行页面跳转(提供的路由地址不存在)
 mBtnGlobalDegrade = findViewById(R.id.btnGlobalDegrade);
        mBtnGlobalDegrade.setOnClickListener(view ->{
            ARouter.getInstance().build("/test1/test1").navigation();
        });
// 参看log 显示如下
2020-07-09 00:04:21.032 4133-4133/com.dashingqi.module.arouter D/MyDegradeService: init: 
2020-07-09 00:04:21.033 4133-4133/com.dashingqi.module.arouter D/MyDegradeService: onLost: 

// 这是全局的降级策略,我们任何页面跳转出现问题 都会回调到自定义DegradeService服务类中的onLost方法中

降级策略的过程分析

单一降级(接口)
  • 单一跳转的降级策略是在navigation()方法中 传入了一个context和一个NavigationCallback接口,我们跟下这个navigation()方法
// ARouter.getInstance().build("") ----> Postcard
// Postcard # navigation()
public Object navigation(Context context, NavigationCallback callback) {
        return ARouter.getInstance().navigation(context, this, -1, callback);
    }
// -----> ARouter # navigation()
public Object navigation(Context mContext, Postcard postcard, int requestCode, NavigationCallback callback) {
        return _ARouter.getInstance().navigation(mContext, postcard, requestCode, callback);
    }
//这回跑到了 _ARouter #navigation
  • _ARouter # navigation()
protected Object navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {
        PretreatmentService pretreatmentService = ARouter.getInstance().navigation(PretreatmentService.class);
        if (null != pretreatmentService && !pretreatmentService.onPretreatment(context, postcard)) {
            // Pretreatment failed, navigation canceled.
            return null;
        }

        try {
            LogisticsCenter.completion(postcard);
        } catch (NoRouteFoundException ex) {
            logger.warning(Consts.TAG, ex.getMessage());

            if (debuggable()) {
                // Show friendly tips for user.
                runInMainThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(mContext, "There's no route matched!\n" +
                                " Path = [" + postcard.getPath() + "]\n" +
                                " Group = [" + postcard.getGroup() + "]", Toast.LENGTH_LONG).show();
                    }
                });
            }

            if (null != callback) {
                callback.onLost(postcard);
            } else {
                // No callback for this invoke, then we use the global degrade service.
                DegradeService degradeService = ARouter.getInstance().navigation(DegradeService.class);
                if (null != degradeService) {
                    degradeService.onLost(context, postcard);
                }
            }

            return null;
        }

        if (null != callback) {
            callback.onFound(postcard);
        }

        if (!postcard.isGreenChannel()) {   // It must be run in async thread, maybe interceptor cost too mush time made ANR.
            interceptorService.doInterceptions(postcard, new InterceptorCallback() {
                /**
                 * Continue process
                 *
                 * @param postcard route meta
                 */
                @Override
                public void onContinue(Postcard postcard) {
                    _navigation(context, postcard, requestCode, callback);
                }

                /**
                 * Interrupt process, pipeline will be destory when this method called.
                 *
                 * @param exception Reson of interrupt.
                 */
                @Override
                public void onInterrupt(Throwable exception) {
                    if (null != callback) {
                        callback.onInterrupt(postcard);
                    }

                    logger.info(Consts.TAG, "Navigation failed, termination by interceptor : " + exception.getMessage());
                }
            });
        } else {
            return _navigation(context, postcard, requestCode, callback);
        }

        return null;
    }
  • 是不是感觉很熟悉,这不就是在页面跳转时最终执行的地方嘛。
    • 首先做了Postcard的数据补充
    • 判断是不是绿色通道,决定了要不要执行拦截器操作
    • 最后没出现问题的话都会执行到 _navigation()
  • 正如上述所说,正常执行会执行_navigation(),那么我们看下针对异常情况是怎么处理的
    • 可以看到 我们抓了NoRouteFoundException 异常
    • 在 LogisticsCenter # completion() 方法中 如果在数据仓库中没有找到对应路由地址我们就会抛出NoRouteFoundException
    • 看下是如何处理的这个异常
      • 可以很明显看到 在catch快中,如果callback不为null,就回调了onLost()方法,这个callback就是在navigation()方法中传入的
  • 到此单一降级策略就破案了
全局的降级策略
  • 同样全局的降级策略也是发生在LogisticsCenter#completion()方法中
  • 列下关键代码
if (null != callback) {
                callback.onLost(postcard);
            } else {
                // No callback for this invoke, then we use the global degrade service.
                DegradeService degradeService = ARouter.getInstance().navigation(DegradeService.class);
                if (null != degradeService) {
                    degradeService.onLost(context, postcard);
                }
            }
// 很好理解,可以看出如果同一个页面跳转,分别设置了单一降级策略和全局降级策略,仅仅会执行单一的降级策略不会执行全局的降级策略。
// 针对是全局降级策略,首先更具IoC中的ByType()方法拿到对应的服务实例(实则就是我们自定义的全局降级策略类)
// 当发现我们自定义的的全局降级策略类,就会回调执行它的onLost()方法

总结

  • 单一的降级策略是针对某一次的页面跳转
  • 全局的降级是针对项目只能够任何一次页面见的路由跳转
  • 如果同时设置了单一和全局的,只会执行单一的全局的就会被覆盖

相关文章

  • ARouter源码分析-降级策略

    简介 通常我们进行页面跳转的时候,调用startActivity()之后我们就无法控制了,之后出现什么问题或者异常...

  • 阿里ARouter拦截器使用及源码解析(二)

    阿里ARouter的分析计划 阿里ARouter使用及源码解析(一) 阿里ARouter拦截器使用及源码解析(二)...

  • Android之旅 -- ARouter 源码分析(二)

    Android之旅 -- ARouter 源码分析(一) 主要介绍了 ARouter 启动 activity 的基...

  • [Android] ARouter

    开源最佳实践:Android平台页面路由框架ARouter Alibaba-ARouter 源码分析笔记 ARou...

  • ARouter源码解析(二)

    arouter-api version : 1.4.1 前言 前几天对 ARouter 的页面跳转源码进行了分析,...

  • ARouter解析七:降级策略

    今天我们接着来学习下阿里今年开源的路由框架ARouter,这个也是我们这个解析系列内容的最后一篇了,后面还会一片总...

  • ARouter源码分析

    ARouter源码解读 以前看优秀的开源项目,看到了页面路由框架ARouter,心想页面路由是个啥东东,于是乎网上...

  • ARouter源码分析

    前言 Android app开发中,经常会用到组件化技术,具体表现就是将各个模块以module的方式集成在主模块(...

  • ARouter源码分析

    目录 1.源码思维导图2.运行时源码分析3.编译期原理3.总结 1.ARouter源码思维导图 这个图是最近总结组...

  • Arouter源码分析

    Arouter核心请求类图 Arouter 和 _Arouter 的关系 _Arouter主要是处理Arouter...

网友评论

      本文标题:ARouter源码分析-降级策略

      本文链接:https://www.haomeiwen.com/subject/zxlncktx.html