美文网首页
ARouter源码分析

ARouter源码分析

作者: 北疆小兵 | 来源:发表于2019-02-11 13:31 被阅读0次

    前言

    Android app开发中,经常会用到组件化技术,具体表现就是将各个模块以module的方式集成在主模块(App壳)中,各个业务module之间代码独立,互不依赖。那业务模块在不存在依赖关系的情况下,如何进行数据交互呢?这就涉及到模块间通讯了。网上有很多开源的模块间通讯方案,例如EventBus,ARouter等,今天来分析一下ARouter源码。

    用法

    • 环境配置
      build.gradle中添加依赖
        api config.thirddependencies.arouter_api
        annotationProcessor config.thirddependencies.arouter_compiler
    
    • 在待启动的目标Activity添加注解
    @Route(path = "/test/activity2")
    public class Test2Activity extends AppCompatActivity {
    
        @Autowired
        String key1;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_test2);
        }
    }
    
    • 启动目标Activity
     ARouter.getInstance()
                           .build("/test/activity2")
                            .navigation();
    

    源码分析

    ARouter.getInstance()
    .build("/test/activity2")调用的是_ARouter中的build方法,返回的是一个Postcard对象

    /**
         * Build postcard by uri
         */
        protected Postcard build(Uri uri) {
            if (null == uri || TextUtils.isEmpty(uri.toString())) {
                throw new HandlerException(Consts.TAG + "Parameter invalid!");
            } else {
                PathReplaceService pService = ARouter.getInstance().navigation(PathReplaceService.class);
                if (null != pService) {
                    uri = pService.forUri(uri);
                }
                return new Postcard(uri.getPath(), extractGroup(uri.getPath()), uri, null);
            }
        }
    

    Postcard调用navigation()方法, 内部其实是调用_ARouter的navigation(),

    /**
         * Use router navigation.
         *
         * @param context     Activity or null.
         * @param postcard    Route metas
         * @param requestCode RequestCode
         * @param callback    cb
         */
        protected Object navigation(final Context context, final Postcard postcard, final int requestCode, final NavigationCallback callback) {
            try {
                //首先对postcard进行一些处理,设置postcard的destination,type,priority 等一些属性值,completion()后面会有分析
                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();
                        }
                    });
                }
                // 如果处理postcard失败,通过 callback 回调失败结果
                // callback为空的情况下,如果有定义全局的降级处理(DegradeService),则使用全局处理
                //降级处理也需要我们自己实现DegradeService接口
                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;
            }
            //回调onFound
            if (null != callback) {
                callback.onFound(postcard);
            }
    
            //目前来说,PROVIDER服务类型,以及FRAGMENT类型不需要通过拦截器外,其他类型均需要通过拦截器
            if (!postcard.isGreenChannel()) {   // It must be run in async thread, maybe interceptor cost too mush time made ANR.
                //如果需要拦截就执行onInterrupt(),否则执行onContinue,在onContinue中执行_navigation
                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;
        }
    
    

    在_ARouter的navigation方法中

    • 调用 LogisticsCenter.completion(postcard);这个方法主要做数据加载处理,执行完这个方法后,目标activity的路由信息就已经设置到postCard对象中了
    • 当调用 LogisticsCenter.completion(postcard)出现异常的时候,判断是NavigationCallback callback参数是否为空,callback不为空的话直接回调callback.onLost(); callback为空的话,调用全局降级服务DegradeService.onLost(), 然后终止整个流程
    • 判断postcard.isGreenChannel()是否需要执行拦截器逻辑,在拦截器中如果需要拦截,则回调onInterrupt(Throwable exception)方法,不需要拦截则会回调onContinue(Postcard postcard), 在onContinue方法中执行_navigation方法取执行Activity跳转逻辑

    相关文章

      网友评论

          本文标题:ARouter源码分析

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