Android 组件化神器之Arouter

组件化项目存在各个模块之间耦合,通信麻烦的问题 ,,为了解决这个问题,阿里巴巴的开发者就搞出了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 源码

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容