IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android组件化神器 --- ARouter -> 正文阅读

[移动开发]Android组件化神器 --- ARouter

组件,就是对数据和方法的简单封装,功能单一,高类聚,是业务划分的最小粒度。组件化是基于可重用的目的,将大型软件系统按照分离关注点的形式,拆分成多个独立组件,使得整个软件是单个或多个组件元件组装起来。那组件之间如何通信呢?这就得益于ARouter。

Android原生的路由方案是Intent的显式和隐式跳转,显式需要对目标的引用,会导致不同页面的耦合,隐式集中配置在manifest中,不利于维护和管理。况且,在组件化开发中,各模块之间无法直接引用,那么,ARouter路由框架就派上用场了。

一个用于帮助 Android App 进行组件化改造的框架 —— 支持模块间的路由、通信、解耦

原理简述

ARouter通过APT技术,生成保存路径(路由path)和被注解(@Router)的组件类的映射关系的类,利用这些保存了映射关系的类,根据用户的请求postcard寻找到要跳转的目标地址,使用Intent跳转。所以,该框架的核心是利用APT生成的映射关系,APT的作用是在编译阶段扫描并处理代码中的注解,然后根据注解输出Java文件。

基本使用

添加依赖和配置,注意,每个使用到ARouter的Module都要引入

plugins {
    id 'com.android.library'
    id 'org.jetbrains.kotlin.android'
    id 'kotlin-kapt'
}
    kapt {
        arguments {
            arg("AROUTER_MODULE_NAME", project.getName())
        }
    }
    implementation 'com.alibaba:arouter-api:1.5.2'
    kapt 'com.alibaba:arouter-compiler:1.5.2'

引入后需要注意的一点是:要在gradle.properties文件中加入下面这个,不然会编译不过去,这也是我遇到的一个小坑。

android.enableJetifier=true

在Application中初始化

        if (isDebug()) {
            ARouter.openLog() //打印日志
            ARouter.openDebug() //开启调试模式,线上需关闭
        }
        ARouter.init(this)

在支持路由的页面上添加如下注解,路径至少需要两级

@Route(path = "/home/HomeActivity")
class HomeActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_home)
    }
}

然后在另一个Activity中,进行跳转

ARouter.getInstance().build("/home/HomeActivity").navigation()

如果需要传递参数的话,可以这样做

            ARouter.getInstance().build("/home/HomeActivity")
                .withString("name", "Uncle Xing")
                .withInt("age", 25)
                .withSerializable("user", User("Uncle Xing", 25))
                .navigation()

然后在目标Activity中通过Autowired接收,ARouter会自动对字段进行赋值,无需主动获取

@Route(path = "/home/HomeActivity")
class HomeActivity : AppCompatActivity() {

    @JvmField
    @Autowired
    var name = ""

    @JvmField
    @Autowired
    var age = 0

    @JvmField
    @Autowired
    var user: User? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_home)
        initView()
    }

    private fun initView() {
        ARouter.getInstance().inject(this)
        
        findViewById<TextView>(R.id.name).text = name
        findViewById<TextView>(R.id.age).text = age.toString()
        findViewById<TextView>(R.id.user).text = user.toString()
    }

}

在组件化开发中,我们通常会有一些公共Module来作为共有功能,那这个时候就可以使用ARouter的依赖注入解耦,组件件的通信,首先我们要声明接口,其他组件通过这个接口来调用方法

interface MyProvider : IProvider {
    fun getData(): String
}

实现类

@Route(path = "/common/MyProviderImpl")
class MyProviderImpl : MyProvider {
    override fun getData(): String {
        return "Welcome to my blog"
    }

    override fun init(context: Context?) {

    }
}

其他组件的Activity就可以这样调用

class MainActivity : AppCompatActivity() {

    /**
     * 当一个接口只有一个实现类的时候,Autowired可以不设置name
     */
    @JvmField
    @Autowired(name = "/common/MyProviderImpl")
    var myProvider: MyProvider? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initView()
    }

    private fun initView() {
        ARouter.getInstance().inject(this)
        findViewById<TextView>(R.id.provider_text).text = myProvider?.getData()
    }

}

上面是使用依赖注入的方式,通过注解标注字段,即可使用,无需主动获取,除此之外,我们也可以使用赖查找的方式,比如上面的代码我们也可以写成这样

class MainActivity : AppCompatActivity() {

    var myProvider: MyProvider? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initView()
    }

    private fun initView() {
//        ARouter.getInstance().inject(this) 这种方式不需要这句
        myProvider =
            ARouter.getInstance().build("/common/MyProviderImpl").navigation() as MyProvider
        /**
         * 发现的方式有byName和byType,如果一个接口只有一个实现的话,也可以使用byType,可以写成
         *  myProvider = ARouter.getInstance().navigation(MyProvider::class.java)
         */
        findViewById<TextView>(R.id.provider_text).text = myProvider?.getData()
    }

}

我们也可以动态注册路由,这样,目标页面和服务就可以不标注 @Route 注解。不过,一般组件化项目都不会这样干,适合部分插件化架构的项目或其他场景。

        ARouter.getInstance().addRouteGroup {
            it["/home/HomeActivity"] = RouteMeta.build(
                RouteType.ACTIVITY,       //路由信息
                HomeActivity::class.java, //目标class
                "/home/HomeActivity", //path
                "home",              //Group,尽量保持和path的第一段相同
                0, 0
            )
        }

注意:同一批次仅允许相同 group 的路由信息注册

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-08-19 19:17:25  更:2022-08-19 19:17:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 4:34:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码