“ARouter解析”


git地址:ARouter

集中式的URL管理:谈到集中式的管理,总是比较蛋疼,多人协同开发的时候,大家都去AndroidManifest.xml中定义各种IntentFilter,使用隐式Intent,最终发现AndroidManifest.xml中充斥着各种Schame, 各种Path,需要经常解决Path重叠覆盖、过多的Activity被导出,引发安全风险等问题
可配置性较差:Manifest限制于xml格式,书写麻烦,配置复杂,可以自定义的东西也较少
跳转过程中无法插手:直接通过Intent的方式跳转,跳转过程开发者无法干预,一些面向切面的事情难以实施,比方说登录、埋点这种非常通用的逻辑,在每个子页面中判断又很不合理,毕竟activity已经实例化了
跨模块无法显式依赖:在App小有规模的时候,我们会对App做水平拆分,按照业务拆分成多个子模块,之间完全解耦,通过打包流程控制App功能,这样方便应对大团队多人协作,互相逻辑不干扰,这时候只能依赖隐式Intent跳转,书写麻烦,成功与否难以控制。


Alibaba的ARoute为了解决这些问题

使用

配置

        compile 'com.alibaba:arouter-api:1.2.1.1'
        annotationProcessor 'com.alibaba:arouter-compiler:1.1.4'

建议在Application中注册

        if (BuildConfig.DEBUG) {           // 这两行必须写在init之前,否则这些配置在init过程中将无效
            ARouter.openLog();     // 打印日志
            ARouter.openDebug();   // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)
        }
        ARouter.init(this); // 尽可能早,推荐在Application中初始化

页面简单跳转

    ARouter.getInstance().build("/study/tab").navigation();

需要跳转的Activity配置

    @Route(path = "/study/tab")
    public class TabActivity extends AppCompatActivity{
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_tab);
        }
    }

AndroidManifest.xml不需要配置schema

    <activity android:name=".TabActivity" />

跳转并携带参数

    ARouter.getInstance().build("/study/testargs")
            .withString("key","Main")
            .navigation();

去读参数

    @Route(path = "/study/testargs")
    public class TestArgsActivity extends AppCompatActivity{

        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_test_args);
            String key = getIntent().getStringExtra("key");
            Toast.makeText(this, key, Toast.LENGTH_SHORT).show();
        }
    }

拦截器可以用来登录啥的巴拉巴拉。。

    @Interceptor(priority = 8)
    public class TestInterceptor implements IInterceptor {
        @Override
        public void process(Postcard postcard, InterceptorCallback callback) {
            Log.e("inter","msg");
            callback.onContinue(postcard);
        }

        @Override
        public void init(Context context) {
        }
    }

通过Uri跳转拦截

    public class SchameFilterActivity extends AppCompatActivity{

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            Uri uri = getIntent().getData();
            if(uri == null){
                finish();
                return;
            }
            Postcard postcard = ARouter.getInstance().build(uri);
    //        for (String key: uri.getQueryParameterNames()){
    //            postcard.withString(key, uri.getQueryParameter(key));
    //        }
            postcard.navigation(null, new NavigationCallback() {
                @Override
                public void onFound(Postcard postcard) {

                }

                @Override
                public void onLost(Postcard postcard) {

                }

                @Override
                public void onArrival(Postcard postcard) {

                }

                @Override
                public void onInterrupt(Postcard postcard) {

                }
            });
            finish();
        }
    }

Uri跳转参数自动读取

    @Route(path = "/study/testargs2")
    public class TestArgs2Activity extends AppCompatActivity{
        @Autowired
        public String key;


        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_test_args);
            ARouter.getInstance().inject(this);
            Toast.makeText(this, key, Toast.LENGTH_SHORT).show();
        }
    }

关于实现原理

s

使用Processor在编译器读取注解的Activity和注解的path,使用javapoet生成ARouterpath 文件 里面保存页面的路由信息

    /**
     * DO NOT EDIT THIS FILE!!! IT WAS GENERATED BY AROUTER. */
    public class ARouter$$Group$$study implements IRouteGroup {
      @Override
      public void loadInto(Map<String, RouteMeta> atlas) {
        atlas.put("/study/tab", RouteMeta.build(RouteType.ACTIVITY, TabActivity.class, "/study/tab", "study", null, -1, -2147483648));
        atlas.put("/study/testargs", RouteMeta.build(RouteType.ACTIVITY, TestArgsActivity.class, "/study/testargs", "study", null, -1, -2147483648));
        atlas.put("/study/testargs2", RouteMeta.build(RouteType.ACTIVITY, TestArgs2Activity.class, "/study/testargs2", "study", new java.util.HashMap<String, Integer>(), -1, -2147483648));
      }
    }

在页面第一次跳转的时候,将路由信息读取到Warehouse的routes,在寻找路由进行跳转。

关于编译时生成代码 请参考 编译时生成代码



本作品由 Tony Zhang 创作,采用 CC BY-NC-SA 3.0 许可协议 进行许可。

Comments