美文网首页androidAndroidAPP & program
Android 组件化神器之Arouter

Android 组件化神器之Arouter

作者: 没有了遇见 | 来源:发表于2022-05-18 14:53 被阅读0次

    组件化项目存在各个模块之间耦合,通信麻烦的问题 ,,为了解决这个问题,阿里巴巴的开发者就搞出了Arouter这个框架,以解决上述问题.

    Arouter 支持模块间的路由、通信、解耦

    1.依赖和配置

    1.1 Java 环境配置方案

    android {
        compileSdkVersion = 30
        buildToolsVersion = "30.0.3"
    
        defaultConfig {
            applicationId "com.wu.material"
            ....
            //ARouter 配置
            javaCompileOptions {
                annotationProcessorOptions {
                    arguments = [AROUTER_MODULE_NAME: project.getName()]
                }
           }
    
    dependencies {
       implementation 'com.alibaba:arouter-api:1.5.1'
       annotationProcessor 'com.alibaba:arouter-compiler:1.2.1'
    
       }
    
     }
    

    1.2 Kotlin 环境配置方案

    plugins {
        id 'com.android.application'
        id 'kotlin-android'
        id 'kotlin-kapt'
    }
    
    
    kapt {
        arguments {
            arg("AROUTER_MODULE_NAME", project.getName())
        }
    }
    
    android {
        compileSdkVersion = 30
        buildToolsVersion = "30.0.3"
     defaultConfig {
            applicationId "com.wu.material"
          }
    
    dependencies {
        implementation 'com.alibaba:arouter-api:1.5.1'
        kapt 'com.alibaba:arouter-compiler:1.2.1'
    }
    
    }
    
    
    

    注意:
    Kotlin 环境和 Java 环境配置不匹配会报错 ARouter::There is no route match the path

    W/ARouter::: ARouter::There is no route match the path [/xxx/xxx], in group [xxx][ ]"
    
    

    2. 在Application初始化

        /**
         * 初始化路由
         */
        private fun initArouter() {
            // 这两行必须写在init之前,否则这些配置在init过程中将无效
            if (BuildConfig.DEBUG) { 
                // 打印日志
                ARouter.openLog();   
                // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)
                ARouter.openDebug(); 
            }
            ARouter.init(this)
        }
    
        override fun onTerminate() {
            super.onTerminate()
            //阿里router需要释放
            ARouter.getInstance().destroy()
        }
    
    
    

    3.Arouter 使用

    3.1 Activity Fragment路由配置以及调用

    // 这里的路径需要注意的是至少需要有两级,/xx/xx
    //注解
    @Route(path = "/arouter/ArouterActivity")
    class ArouterActivity:AppCompatActivity() {
    ...
    //获取数据
    var key2=getIntent().getStringExtra(key2")
    
    }
    
    // 跳转
    ARouter.getInstance().build("/arouter/ArouterActivity")
                .withLong("key1", 1l)
                .withString("key2", "888")
                .withObject("key3", new UserInfo("Jack", "Rose"))
                .navigation();
    
    
    额外方法:
    // 构建标准的路由请求
    ARouter.getInstance().build("/home/main").navigation();
    
    // 构建标准的路由请求,并指定分组
    ARouter.getInstance().build("/home/main", "ap").navigation();
    
    // 构建标准的路由请求,通过Uri直接解析
    Uri uri;
    ARouter.getInstance().build(uri).navigation();
    
    // 构建标准的路由请求,startActivityForResult
    // navigation的第一个参数必须是Activity,第二个参数则是RequestCode
    ARouter.getInstance().build("/home/main", "ap").navigation(this, 5);
    
    // 直接传递Bundle
    Bundle params = new Bundle();
    ARouter.getInstance()
        .build("/home/main")
        .with(params)
        .navigation();
    
    // 指定Flag
    ARouter.getInstance()
        .build("/home/main")
        .withFlags();
        .navigation();
    
    // 获取Fragment
    Fragment fragment = (Fragment) ARouter.getInstance().build("/test/fragment").navigation();
                        
    // 对象传递
    ARouter.getInstance()
        .withObject("key", new TestObj("Jack", "Rose"))
        .navigation();
    
    // 觉得接口不够多,可以直接拿出Bundle赋值
    ARouter.getInstance()
            .build("/home/main")
            .getExtra();
    
    // 转场动画(常规方式)
    ARouter.getInstance()
        .build("/test/activity2")
        .withTransition(R.anim.slide_in_bottom, R.anim.slide_out_bottom)
        .navigation(this);
    
    // 转场动画(API16+)
    ActivityOptionsCompat compat = ActivityOptionsCompat.
        makeScaleUpAnimation(v, v.getWidth() / 2, v.getHeight() / 2, 0, 0);
    
    // ps. makeSceneTransitionAnimation 使用共享元素的时候,需要在navigation方法中传入当前Activity
    
    ARouter.getInstance()
        .build("/test/activity2")
        .withOptionsCompat(compat)
        .navigation();
            
    // 使用绿色通道(跳过所有的拦截器)
    ARouter.getInstance().build("/home/main").greenChannel().navigation();
    
    // 使用自己的日志工具打印日志
    ARouter.setLogger();
    
    // 使用自己提供的线程池
    ARouter.setExecutor();
    

    3.2 Arouter 路由跳转的拦截器 IInterceptor(拦截跳转过程,面向切面编程)

    
    // 比较经典的应用就是在跳转过程中处理登陆事件,这样就不需要在目标页重复做登陆检查
    // 拦截器会在跳转之间执行,多个拦截器会按优先级顺序依次执行
    @Interceptor(priority = 10, name = "测试拦截器")
    class ArouterInterceptor : IInterceptor {
        var mContext: Context? = null
        
        // 拦截器的初始化,会在sdk初始化的时候调用该方法,仅会调用一次
        override fun init(context: Context?) {
            mContext = context
        }
    
    
        override fun process(postcard: Postcard?, callback: InterceptorCallback?) {
            Log.e("传递的数据", "")
            if (postcard != null) {
                var service = ARouter.getInstance().navigation(UserService::class.java)
                //跳转过程中添加数据以及处理数据
                postcard!!.extras.putString("uid", service.getUid())
            }
            if (callback != null) {
                //传递到页面
                callback!!.onContinue(postcard);
            }
            // 觉得有问题,中断路由流程
            // callback.onInterrupt(new RuntimeException("我觉得有点异常"));
    
            // 以上两种至少需要调用其中一种,否则不会继续路由
        }
    
    
    }
    

    3.3 处理跳转结果

     // 增加整个跳转过程的监听 ARouter.getInstance().build("/rv/MediaPlayerActivity").withString("name", "测试名字数据")
                .navigation(mContext, object : NavigationCallback {
                    override fun onFound(postcard: Postcard?) {
                        Log.e("Arouter", "onFound")
                    }
    
                    override fun onLost(postcard: Postcard?) {
                        Log.e("Arouter", "onLost")
                    }
    
                    override fun onArrival(postcard: Postcard?) {
                        Log.e("Arouter", "onArrival")
                    }
    
                    override fun onInterrupt(postcard: Postcard?) {
                        Log.e("Arouter", "onInterrupt")
                    }
                })
    
    

    3.4 通过依赖注入解耦:服务管理

    /**
     * @author wkq
     *
     * @date 2022年05月17日 16:45
     *
     *@des  创建服务
     *
     */
    interface UserService:IProvider {
        fun getUid():String?
        fun getName():String?
        fun getFace():String?
    }
    
    
    
    /**
     * @author wkq
     *
     * @date 2022年05月17日 16:46
     *
     *@des  实现服务
     *
     */
    // 注解
    @Route(path = "/service/UserSericice")
    class UserServiceImpl:UserService {
        override fun getUid(): String? {
            return nickUid
        }
    
        override fun getName(): String? {
            return nickName
        }
    
        override fun getFace(): String? {
            return nickFace
        }
        var nickName=""
        var nickFace=""
        var nickUid=""
        override fun init(context: Context?) {
            nickName="我是测试"
            nickFace="我是头像"
            nickUid="10010"
        }
    
    }
    
    
    //调用IProvider 获取数据
    
    //方法1
     var service = ARouter.getInstance().navigation(UserService::class.java)
     var name= service.getName()
            
    //方法2 
    var userServiceImpl =ARouter.getInstance().build("/service/UserSericice").navigation() as UserServiceImpl
    var userName = userServiceImpl.getName()
    
    

    总结
    简单的调用了一下Arouter的一些方法,整体功能够用了,在模块化架构的时候Arouter是个利器,一些高级别使用方式没有一一列举,又兴趣的可以去官网看一下,地址放在结尾

    欢迎点赞!!!

    资源

    1.Arouter 文档

    2.Demo 源码

    相关文章

      网友评论

        本文标题:Android 组件化神器之Arouter

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