`

ARouter 在多 module 项目中实战

阅读更多

本文已首发微信公众号「code小生」,大家可以搜索关注,专注安卓技术分享。

必要说明

本文仅作案例演示,方便学习和掌握基础知识,不进行源码级别的探究。下面先明确一下能实现的功能和用到的技术点以及环境。

技术点:

  • 多module工程,有baseLib和主APP以及多业务module
  • 多module,实现某个module可独立运行
  • 多module之间跳转,使用ARouter框架
  • ARouter拦截器使用

环境:

  • Android Studio4.1.2
  • 语言:Java
  • 手机:三星A6s Android10

路由应用场景

安卓的项目结构发展越来越倾向于多模块,而模块间的跳转如果使用原生方式(Intent跳转),那么会随着项目的发展壮大,最终导致错综复杂的import xxx,从而给维护带来很大的麻烦,如下图这样:

不使用路由的多模块不使用路由的多模块

黑色线条: 表示依赖关系,有了依赖,就可以在当前模块引用其他模块的类,就可以使用Intent 跳转。
蓝色线条: 表示从app模块要跳转login,live,work模块的某个页面,那么必须依赖对应模块才可以引用到相关类,从而实现跳转。
红色线条: 业务需要,从work模块可以直接进入直播间,那么work模块就必须依赖live模块;反之亦然。
绿色线条: 当用户没有登录,或者登录状态失效,亦或者账号在别处登录了,那么需要从当前模块跳转到login模块,所以其他基础模块都要依赖login模块。

这样随着项目功能的拓展,带来的问题就很明显了。

ARouter的出现,就很好的解决了这个问题,官网地址:https://github.com/alibaba/ARouter/ ,其功能很强大,对于多模块的项目,无论是否组件化,都很好的解决了相互依赖和跳转带来的维护成本。如下简易图:

使用路由的多模块使用路由的多模块

黑色线条: 表示依赖关系,这里的依赖主要是解决资源共用问题,而不是跳转。如果用不到baselib中的资源,那么无需依赖。
其他虚线条: 表示无需相互依赖,就可以实现页面跳转和通信,这就是路由的强大之处。

工程 Module 配置

新建工程

我这里命名为MyArouter,然后分别 new Module:baseLibcirclehome 选择 Android Library 类型,编译完成如下图,则为正常状态;

添加依赖关系

win 系统通过快捷键 Ctrl+Shift+Alt+S 调出 Project Structure 面板,当然你也可以通过点击菜单栏的File->Project Structure 来打开这个面板。

Project StructureProject Structure

如图选择不同的模块,添加依赖模块即可,我这里的依赖是这样的:

  • app模块依赖:baseLibcirclehome
  • baseLib模块:不依赖任何功能模块
  • circle模块依赖:baseLib
  • home模块依赖:baseLib

模块说明

  • baseLib:项目的公共基础模块,一般可以包括共用的工具类、公共资源、公共代码片段、共用三方引用等等可以放在这里,这样做可以避免很多的重复代码、提高代码的可阅读性和程序的易维护。
  • app:是整个项目的宿主模块,也就是说该模块的优先级是高于其他功能模块的,因为程序的主入口是这里。
  • 其他模块,都是按照业务功能来划分,负责具体的业务。

工程 ARouter 配置

第一步:baseLib模块配置

打开baseLib下的build.gradle文件,在dependencies下添加如下代码

api 'com.alibaba:arouter-api:1.5.2'

接着在baseLib下新建 BaseApplication 类,完整代码如下:

public class BaseApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        initRouter(this);
    }

    public static void initRouter(Application application) {
        if (BuildConfig.DEBUG) {
            ARouter.openLog();
            ARouter.openDebug();
        }
        ARouter.init(application);
    }

}

然后新建类ARouterPath,该类的功能是提供统一的路由跳转页面路径,也就是ARouter中的path值;

public class ARouterPath {

    public static final String CIRCLE_CIRCLE="/circle/home";

}

第二步:其他模块配置

依次在appcirclehome模块,打开对应的build.gradle文件

  • dependencies下添加如下代码
annotationProcessor 'com.alibaba:arouter-compiler:1.5.2'
  • defaultConfig下添加如下代码
javaCompileOptions {
    annotationProcessorOptions {
        arguments = [AROUTER_MODULE_NAME: project.getName()]
    }
}

到这里,其实路由的引用配置已经完成,但我们还没有添加Application,也很简单了,在app模块下,新建AppApplication继承自BaseApplication,并将其添加到该模块下的清单文件中。

public class AppApplication extends BaseApplication {

}

这里不做实现是因为演示demo,用不到第三方的东西,实际开发中根据需求进行初始化即可。之所以继承,是因为前面我们已经初始化了路由配置。

测试 ARouter 跳转

配置工作我们已经做完了,本文的主要目的就是测试页面跳转,当然跳转就会包含是否携带参数、跳转是否需要有返回值、以及没有依赖关系的模块间是否可跳转,下面进行分组测试:

tips:为了避免写findViewById() ,我这里使用了ViewBinding,用法很简单,一看就懂,这里不做详细说明。

模块内使用路由跳转

模块内的话,完全可以使用intent方式跳转,但本文的主题是探究路由的跳转用法,我这里以app模块内跳转为例,新建了一个名为MyInfoActivity的页面,显示默认值,通过在MainActivity携带参数跳转赋值来展示使用示例。

跳转传参跳转传参

如果你的配置都没有错,还是无法跳转,那么卸载APP重新运行,就是Ok的,因为路由地址path有映射,缓存下来了,虽然后面改了,但走的还是缓存。

传参说明

ARouter提供了多种方式传递参数,也支持原生的参数值类型,如下图:

ARouter传参方法ARouter传参方法

这里不演示全部方法的使用,只要会了下面几个常用的,其他都类似。

  • with(Bundle bundle):如果要传递多个参数,推荐使用该方法。
  • withBundle(String key, Bundle bundle):依然是传递一个Bundle,但可以自定义key .
  • with封装数据类型(String key, 基本数据类型值):如果只传递一个参数,且是基本数据类型,那么这些方法非常实用。

其他常使用的像传递序列化对象、集合等,大家自行尝试。下面说下如何取参数。如下代码是我们的MyInfoActivity的传参:

ARouter.getInstance().build(ARouterPath.APP_MY_INFO)
          .withInt(KEY_TYPE, 100)
          .withString(KEY_NAME, "codexiaosheng")
          .withString(KEY_WEIXIN, "xiaoshengcode")
          .navigation();

补充:可能有细心的朋友注意到,那带返回值方式的跳转如何写呢?

navigationnavigation

  • 第三个方法就等同于我们原生写法startActivityForResult()
  • 第四个方法还提供了监听,后面要分享的拦截功能就会使用到。

取参说明

对应上面三个传参方法:

  • with(Bundle bundle):取参数通过getIntent().getExtras()获得Bundle,然后就和我们原生用法相同。
  • withBundle(String key, Bundle bundle)with封装数据类型(String key, 基本数据类型值):取参数方式相同,可以先看一下上面给出的MyInfoActivity的代码:
@Route(path = ARouterPath.APP_MY_INFO)
public class MyInfoActivity extends AppCompatActivity {

    private ActivityMyInfoBinding myInfoBinding;

    @Autowired
    public int u_type;
    @Autowired(name = MainActivity.KEY_NAME)
    public String uName;
    @Autowired(name = MainActivity.KEY_WEIXIN)
    public String uWeixin;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        myInfoBinding = ActivityMyInfoBinding.inflate(getLayoutInflater());
        setContentView(myInfoBinding.getRoot());

        ARouter.getInstance().inject(this);

        myInfoBinding.tvName.setText("name:" + uName + " 用户类型:" + u_type);
        myInfoBinding.tvWeixin.setText("weixin:" + uWeixin);
    }

}

可以看到这里和我们平时取参数有几点不同:

  1. 使用了@Autowired注解
  2. 多了ARouter.getInstance().inject(this);这行代码
  3. 接收参数的字段都是public修饰符
  4. 并没有显式的getXXX取值代码

@Autowired注解的说明:

  • 所注解的变量必须是public
  • 如果变量的名字和传参的key不相同,那么需要手动给注解添加name值,即传参的key.

with(Bundle bundle)这种方式传参方式,其他方式要在接收参数的页面添加下面这行代码:

ARouter.getInstance().inject(this);

如果使用的with(Bundle bundle)传参方式,那么取参数通过getIntent().getExtras()获得Bundle,操作即可。

综合看起来,还是比较简单的,少了很多判断代码。

模块间相互跳转

这里我使用with(Bundle bundle)方式传递参数做演示。先来看一个总体的效果:

这种方式传递参数,在接收的页面上既不用添加@Autowired注解,也不用添加ARouter.getInstance().inject(this);这行代码,使用我们原来的方式getIntent().getExtras()即可。

上面的演示效果中涉及app模块跳转homecircle模块、home模块和circle模块相互跳转,还记得前面的依赖关系吗?homecircle直接是没有依赖关系的,但可以通过路由直接跳转,如果我们项目的module比较多,这就会很方便,降低代码耦合性。

看一下跳转home模块的代码:

// 跳转home模块页面
mainBinding.jumpHomePage.setOnClickListener(v -> {
    if (mainBinding.cbHome.isChecked()) {
        Bundle bundle = new Bundle();
        bundle.putInt(KEY_TYPE, 500);
        bundle.putString(KEY_NAME, "home module");
        bundle.putString(KEY_WEIXIN, "is home module~");

        ARouter.getInstance().build(ARouterPath.HOME_HOME).with(bundle).navigation();
    } else {
        ARouter.getInstance().build(ARouterPath.HOME_HOME).navigation();
    }
});

核心代码都贴出来了,到这基本的演示功能就完成了,本文是以java来演示的,kotlin配置参考官网。

关于路由的高级使用,比如:拦截以及模块可单独运行,下一篇博客会揭晓。

跳转原理

ARouter 通过注解自动注册并且在编译期间生成映射关系,在运行的时候就可以加载文件,通过 path 就可以顺利跳转到目标页面。

本文总结

  1. 看不到对应的R.layout.xxx_layout文件名了,可以通过点击XXXBinding.getRoot()跳转至对应xml
  2. 如果项目各模块间跳转比较多,建议统一使用路由跳转
  3. ARouter还可以跳转fragment,具体使用查看官方demo
  4. 常见的跳转动画设置,ARouter跳转也是可以的,传入动画资源文件id即可

本文全部代码获取:关注微信公众号code小生回复arouter

分享到:
评论

相关推荐

    intellij idea 设置多module路径.docx

    在多module项目中,如果我们希望这个值对应于当前执行的module的根目录,那么我们需要进行相应的配置调整。 步骤如下: 1. 打开IntelliJ IDEA,进入你的项目。 2. 转到 `Run` 菜单,然后选择 `Edit Configurations...

    Android简单使用ARouter

    在项目中集成ARouter,需要在`build.gradle`文件中添加依赖,并在项目的主Module执行初始化操作。首先,添加依赖: ``` implementation 'com.alibaba.android:arouter-api:1.6.4' implementation '...

    spring MVC 多module demo

    6. **集成与部署**:在多module项目中,最终会将所有模块打包成一个可部署的war或ear文件。Maven的`mvn install`命令会自动处理这个过程,生成的war文件可以直接部署到应用服务器,如Tomcat、Jetty等。 7. **优点**...

    Intellij, 多module

    6. **运行与调试**:在多module项目中,你可以选择单独运行或调试单个模块,也可以设置整个项目的运行配置,如应用服务器部署。IntelliJ IDEA提供了丰富的运行配置选项,包括对单个测试类、模块甚至整个项目的运行和...

    maven-module多模块依赖项目在eclipse中搭建与开发

    Maven-module项目可以把较大的项目按照功能或者层次进行横向与纵向的模块化分割。项目结构是父项目-子模块的结构进行组织。整个项目以pom型项目进行组织,其模块可以是jar项目,也可以是war项目,也可以pom项目。...

    ARouter路由框架的使用

    1. **添加依赖**:在项目的`build.gradle`文件中添加ARouter的相关依赖库。 - 示例代码:添加最新的API版本和compiler版本(可通过GitHub查询)。 2. **初始化ARouter** 在自定义的`MyApplication`类中完成...

    Android Studio 多层级 Module 对 aar 引用问题解决方法

    问题:有个arr文件被放到Module A中引用,现在Module B又依赖了Module A,则在编译过程中会发生错误,Module B找不到aar文件。(同时如果又有Module C 依赖了Module B,C也会出同样的问题) 解法: 1、正常给一个...

    Android-Androidstudio多module混淆成一个Jar

    在Android开发过程中,有时我们需要将多个Module打包成一个单一的Jar文件,以便于代码管理和分发。Android Studio作为Google官方推荐的Android开发IDE,提供了强大的功能支持,包括构建脚本和Gradle插件,使得这一...

    gs-multi-module, 创建多模块项目.zip

    gs-multi-module, 创建多模块项目 目录你将构建什么。你需要什么。创建一个 root 项目项目。创建目录结构用于多 MODULE 项目的 Gradle配置用于多 MODULE 项目的 Gradle配置用于多 MODULE 项目的 Maven 配置用于多

    Android Studio多moduleAAR示例

    在多module项目中,我们可以将通用功能封装成Library Module,然后在主Application Module中引用它,以实现代码重用。 在创建AAR库时,你需要遵循以下步骤: 1. **创建Library Module**:在Android Studio中,选择...

    32_Vue3+TS项目实战1

    本文将详细讲解 Vue3+TS 项目实战中的一些重要知识点,包括 tsconfig.json 配置选项、axios 库的使用和配置、环境变量的设置等。 一、tsconfig.json 配置选项 tsconfig.json 是用于配置 TypeScript 编译时的配置...

    关于IAR中摸个“xxx”在两个module中redefined的error问题

    - 在多个源文件中包含相同的头文件可以确保一致性。 - 使用`#include`指令来引入头文件。 2. **.c文件(源文件)**: - 源文件包含实际的代码实现。 - 定义变量、实现函数体等。 - 当多个源文件共享某些变量或...

    如何使用eclipse搭建maven多module项目(构建父子项目)

    在配置子模块项目的依赖关系时,需要在子模块项目的pom.xml文件中添加父项目的依赖关系。可以按照以下步骤添加: 1. 在子模块项目的pom.xml文件中,添加父项目的依赖关系。 2. 在子模块项目的pom.xml文件中,添加子...

    framework-module的使用

    Framework-Module 是一个关键的概念在 iOS 开发中,它允许我们将代码组织成小的、独立的模块,以便更好地管理和维护项目。模块化可以提高代码的可读性、可维护性和重用性。 头文件管理 在 Framework 项目中,...

    vue 之 css module的使用方法

    前言 最近学习webpack看到了一个新鲜的东西,之前都是通过scoped来区别类名,秉着任何时候学习都不晚的心情,作为小白的我也想揭揭css module的...动手之前先配置项目,网上很多文章说需要下载css-loader插件,Vue中的v

    详解IDEA多module项目maven依赖的一些说明

    在多模块项目结构中,可以通过module自己的pom.xml文件来配置依赖关系。例如,一个controller模块可以依赖service模块,service模块可以依赖model模块,以此类推。 二、Maven依赖管理 Maven依赖管理是多模块项目...

    一个多module自动打包并合并成单个jar包的gradle插件,适合sdk模块化打包.zip

    在IT行业中,模块化开发是提高代码复用性和项目可维护性的重要手段。随着Java生态系统的不断发展,Gradle作为一款强大的构建工具,逐渐成为许多开发者首选的自动化构建系统。本项目是一个专门针对Java SDK模块化的...

    第十一章_OCR文字识别项目实战.zip

    在本项目实战中,我们将深入探索OCR(Optical Character Recognition,光学字符识别)技术,这是一种将图像中的文本转换为机器编码文本的过程。OCR技术广泛应用于文档扫描、票据自动处理、车牌识别等领域,大大提升...

    ARouter组件demo

    在"ModuleDemo"这个子项目中,你应该能看到具体如何设置注解、初始化ARouter、跳转页面以及实现其他相关功能的示例代码。通过分析和运行这个demo,你可以更好地理解ARouter的工作原理,并将其应用到自己的项目中。

Global site tag (gtag.js) - Google Analytics