美文网首页
ARouter的使用以及遇到的问题

ARouter的使用以及遇到的问题

作者: 成虫_62d0 | 来源:发表于2019-03-25 16:58 被阅读0次

    app随着业务的越来越复杂,代码量越来越大,导致了各种问题亟待解决:

    • 整体打包速度变慢。
    • 业务间耦合较高。

    为了解决上述问题,我们进行了组件化重构,本文不对组件化方案进行详细的介绍。组件化重构又要解决组件与组件之间的耦合问题—例如页面之间的跳转。所以在项目中引入了 ARouter

    本文将介绍ARouter的使用以及使用中遇到的问题。

    ARouter支持的特性

    • 支持url标准解析以及跳转(url绑定特定的activity页面),自动注入参数。

    • 多组件支持(解耦)

    • 支持跳转拦截处理—登录,统计以及其他逻辑

    • 跨组件通信解耦以及依赖倒置

    ARouter典型应用场景

    • 不同组件之间activity的跳转
    • h5页面跳转到activity
    • 登录拦截处理—很多跳转要先判断是否登录,如果没有登录跳转到登录页面

    ARouter的使用姿势

    1. 配置

      • buid.gradle文件添加依赖和配置

        android {
            defaultConfig {
                ...
                javaCompileOptions {
                    annotationProcessorOptions {
                        arguments = [AROUTER_MODULE_NAME: project.getName()]
                    }
                }
            }
        }
        
        dependencies {
            // Replace with the latest version
            compile 'com.alibaba:arouter-api:?'
            annotationProcessor 'com.alibaba:arouter-compiler:?'
            ...
        }
        
      • 在代码中添加注解

        @Route(path = "/test/activity")
        public class YourActivity extend Activity {
            ...
        }
        
      • 在application中初始化

        if (isDebug()) {           // These two lines must be written before init, otherwise these configurations will be invalid in the init process
            ARouter.openLog();     // Print log
            ARouter.openDebug();   // Turn on debugging mode (If you are running in InstantRun mode, you must turn on debug mode! Online version needs to be closed, otherwise there is a security risk)
        }
        ARouter.init(mApplication); // As early as possible, it is recommended to initialize in the Application
        

        这里注意注释,在debug模式下必须要在初始化之前调用ARouter.openLog() ARouter.openDebug

      • 代码调用

        // 1. Simple jump within application (Jump via URL in 'Advanced usage')
        ARouter.getInstance().build("/test/activity").navigation();
        
        // 2. Jump with parameters
        ARouter.getInstance().build("/test/1")
                    .withLong("key1", 666L)
                    .withString("key3", "888")
                    .withObject("key4", new Test("Jack", "Rose"))
                    .navigation();
        
      • proguard文件的配置

        -keep public class com.alibaba.android.arouter.routes.**{*;}
        -keep public class com.alibaba.android.arouter.facade.**{*;}
        -keep class * implements com.alibaba.android.arouter.facade.template.ISyringe{*;}
        
        # If you use the byType method to obtain Service, add the following rules to protect the interface:
        -keep interface * implements com.alibaba.android.arouter.facade.template.IProvider
        
        # If single-type injection is used, that is, no interface is defined to implement IProvider, the following rules need to be added to protect the implementation
        # -keep class * implements com.alibaba.android.arouter.facade.template.IProvider
        
    2. 使用场景

      • 根据url跳转

        public class SchameFilterActivity extends Activity {
         @Override
         protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
          
             Uri uri = getIntent().getData();
             ARouter.getInstance().build(uri).navigation();
             finish();
         }
          }
        
        <activity android:name=".activity.SchameFilterActivity">
            <!-- Schame -->
            <intent-filter>
                <data
                    android:host="m.aliyun.com"
                    android:scheme="arouter"/>
        
                <action android:name="android.intent.action.VIEW"/>
        
                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>
            </intent-filter>
        </activity>
        
      • 解析参数

        @Route(path = "/test/activity")
        public class Test1Activity extends Activity {
            @Autowired
             public String name;
            @Autowired
            int age;
            @Autowired(name = "girl") // Map different parameters in the URL by name
            boolean boy;
            @Autowired
            TestObj obj; 
            
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                ARouter.getInstance().inject(this);
        
                // ARouter will automatically set value of fields
                Log.d("param", name + age + boy);
            }
        

        ARouter.getInstance().inject(this);这行代码一定要在oncreate中调用。还支持自定义的参数解析,有这方面需求的可以去ARouter的github页面

      • 面向切面的拦截器

        // A more classic application is to handle login events during a jump so that there is no need to repeat the login check on the target page.
        // Interceptors will be executed between jumps, multiple interceptors will be executed in order of priority
        @Interceptor(priority = 8, name = "test interceptor")
        public class TestInterceptor implements IInterceptor {
            @Override
            public void process(Postcard postcard, InterceptorCallback callback) {
                ...
                // No problem! hand over control to the framework
                callback.onContinue(postcard);  
                
                // Interrupt routing process
                // callback.onInterrupt(new RuntimeException("Something exception"));      
        
                // The above two types need to call at least one of them, otherwise it will not continue routing
            }
        
            @Override
            public void init(Context context) {
                // Interceptor initialization, this method will be called when sdk is initialized, it will only be called once
            }
        }
        
      • 跳转回调

        // U can get the result of a single jump
        ARouter.getInstance().build("/test/1").navigation(this, new NavigationCallback() {
            @Override
            public void onFound(Postcard postcard) {
            ...
            }
        
            @Override
            public void onLost(Postcard postcard) {
            ...
            }
        });
        

    遇到的问题

    • ARouter.getInstance().inject(this);
      我们有一个singletask启动模式的activity,在onNewIntent方法中调用ARouter.getInstance().inject(this);得不到参数,查看ARouter在build过程中生成的代码可以知道它是调用了activity的getIntent来获取参数的,但是onNewIntent中的intent和在onCreate方法中的intent并不相同,所以需要在onNewIntent方法中调用setIntent方法,然后就能得到参数了。

      ARouter::Compiler >>> No module name, for more information, look at gradle log.
      检查项目依赖的全部module包括module依赖的module(没有页面的module也算),在每个module的 build.gradle中加上下面的代码。

    defaultConfig {
        
            javaCompileOptions {
                annotationProcessorOptions {
                    arguments = [ AROUTER_MODULE_NAME : project.getName() ]
                }
            }
    }
    
    • ARouter there's no route matched

    不同module的一级路径必须不同,否则会导致一个moudle中的一级路径失效

    下面是抛出异常的源代码

        public synchronized static void completion(Postcard postcard) {
        if (null == postcard) {
            throw new NoRouteFoundException(TAG + "No postcard!");
        }
    
        //查找RouteMeta对象,如果存在说明路由成功,如果失败说明还没有被加载或者这个path就是错误的
        RouteMeta routeMeta = Warehouse.routes.get(postcard.getPath());
        if (null == routeMeta) {
          // 通过groupsIndex去找IRouteGroup的实现类
            Class<? extends IRouteGroup> groupMeta = Warehouse.groupsIndex.get(postcard.getGroup());
            if (null == groupMeta) {
                throw new NoRouteFoundException(TAG + "There is no route match the path [" + postcard.getPath() + "], in group [" + postcard.getGroup() + "]");
            } else {
                // 通过反射获取IRouteGroup的实现类,然后加载到内存
                IRouteGroup iGroupInstance = groupMeta.getConstructor().newInstance();
                iGroupInstance.loadInto(Warehouse.routes);
                // 加载到内存后Warehouse.groupsIndex去掉这个group
                Warehouse.groupsIndex.remove(postcard.getGroup());
            }
        } else {
            //查找到路由地址
            。。。。。
        }
    }
    
    

    相关文章

      网友评论

          本文标题:ARouter的使用以及遇到的问题

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