当前位置: 首页 > article >正文

【Android】初始路由框架及ARouter原理

路由框架

定义

路由框架是用于管理应用程序中不同组件(如页面、活动、模块等)之间导航和通信的工具。它通常提供了一种简化的方式来处理路由、参数传递和组件间的调用,使得开发者能够更加方便地管理应用的结构和导航。

路由框架的主要功能包括

  1. 页面导航:允许在不同的页面或组件之间进行跳转,通常支持传递参数。
  2. 路由配置:通过配置文件或注解方式定义路由规则,使得路由逻辑更加清晰。
  3. 参数解析:能够解析并传递参数,确保不同组件之间的数据共享。
  4. 解耦:降低了组件之间的耦合度,使得每个模块可以独立开发和测试。
  5. 动态路由:支持在运行时动态添加或修改路由,增强了灵活性。

为什么需要路由框架?

我们来简单说一下路由框架存在的意义:

  1. 显示Intent:项目庞大以后,类依赖耦合太大,不适合组件化拆分
  2. 隐式Intent:协作开发困难,调用的时候不知道调什么参数
  3. 每个注册了Scheme的Activity都可以直接打开,有安全风险
  4. AndroidMainfest集中式管理比较臃肿
  5. 无法动态修改路由,如果页面出错,无法动态降级
  6. 无法动态拦截跳转,例如未登录的情况下,打开登录页面,登录成功后接着打开刚才想打开的页面
  7. H5、Android、iOS地址不一样,不利于统一跳转
  8. 在一些复杂的业务场景下(比如电商),灵活性比较强,很多功能都是运营人员动态配置的,比如下发一个活动页面,我们事先并不知道具体的目标页面,但如果事先做了约定,提前做好页面映射,便可以自由配置。
  9. 简化代码,数行跳转代码精简成一行代码,这个大家应该都很容易理解,无非就是对代码块的封装。

简单实现

新建router-api模块,新建Router类:

public class Router {

    private static volatile Router mInstance;//使用 volatile 关键字防止指令重排序,确保在多线程环境中 mInstance 的正确性

    public static Router getInstance() {
        if (mInstance == null) {
            synchronized (Router.class) {
                if (mInstance == null) {
                    mInstance = new Router();
                }
            }
        }
        return mInstance;
    }

    private static Map<String, Class<? extends Activity>> routers = new HashMap<>();

    public void register(String path, Class<? extends Activity> cls) {
        routers.put(path, cls);
    }

    public void startActivity(Activity activity, String path) {
        Class<? extends Activity> cls = routers.get(path);
        if (cls != null) {
            Intent intent = new Intent(activity, cls);
            activity.startActivity(intent);
        }
    }
}

**public static Router getInstance() **:这个方法用于获取 Router 类的实例。它首先检查 mInstance 是否为 null,如果是,则进入同步块。在同步块中再次检查 mInstance 是否为 null,如果是,则创建一个新的 Router 实例。这种方法称为双重校验锁,它确保了在多线程环境中只创建一个 Router 实例。

当我们想在另一个模块中使用Router的时候,需要先添加依赖:

implementation(project(":router-api"))

然后就可以进行使用了。

ARouter

简介

ARouter 是一个强大的 Android 路由框架,用于在 Android 应用中实现模块间的页面跳转、服务调用和依赖注入等功能。它主要用于简化和规范应用模块化开发中的页面导航,并提供了灵活的跳转配置和参数传递功能。

主要功能:

  • 页面跳转:ARouter 可以在模块化的应用架构中实现模块之间的页面跳转,而不需要直接引用其他模块,解耦页面间的依赖关系。
  • 服务管理:支持跨模块的服务调用,例如从一个模块中获取另一个模块提供的功能。
  • 依赖注入:支持在模块之间实现依赖注入,提供更灵活的服务调用方式。
  • 页面拦截:可以在跳转前进行拦截,例如进行登录校验、权限检查等。

使用方法

1. 配置

在build.gradle中进行配置:

implementation("com.alibaba:arouter-api:1.5.2")
annotationProcessor("com.alibaba:arouter-compiler:1.5.2")

2. 添加ARouter路由注解

@Route(path = "/test/RouteActivity")
public class RouteActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
}

上面的代码就是在目标Activity类上面声明Route path注解,以此对应,跳转如果不对应路径,框架会Toast说路径不匹配。

3. 初始化ARouter

在Activity同级包里,创建一个新的类RouteApplication.java继承Application:

public class RouteApplication extends Application {
    //ARouter调用开关
    private boolean isDebugARouter=true;

    @Override
    public void onCreate() {
        super.onCreate();
        if (isDebugARouter) {
            // 打印日志
            ARouter.openLog();
            // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)
            ARouter.openDebug();
        }
        ARouter.init(this);
    }
}

修改AndroidManifest.xml中内容,加入:

android:name=".RouteApplication"

4. 发起路由操作

 ARouter.getInstance().build("/test/RouteActivity").navigation();

build() 方法是 ARouter 中用于创建路由请求的核心方法。它会根据给定的路径(例如 "/test/RouteActivity")生成一个 Postcard 对象,该对象保存了目标页面或服务的所有路由信息,包括路径、分组和传递的参数等。

navigation() 方法是 ARouter 框架的核心方法,用于执行实际的跳转操作。它会根据 build() 方法中配置的路径和参数信息,完成页面跳转或服务调用的逻辑。

1>传递参数

可以通过 withXXX() 系列方法传递参数,支持常见的数据类型,例如 Stringintboolean 等:

ARouter.getInstance().build("/test/RouteActivity")
    .withString("key", "value")
    .withInt("age", 25)
    .withBoolean("isStudent", true)
    .navigation();

RouteActivity 中,可以通过 getIntent().getExtras() 方式获取这些参数,也可以使用 @Autowired 注解(需要 ARouter 的 inject() 方法)来自动注入参数:

ARouter.getInstance().build("/test/RouteActivity")
    .withString("username", "xiaoduyyy")
    .withInt("age", 19)
    .navigation();
@Route(path = "/test/RouteActivity")
public class RouteActivity extends AppCompatActivity {

    @Autowired
    public String username;  // 字段名与传递参数键名一致

    @Autowired(name = "age")  // 显式指定键名
    public int userAge;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_route);

        // 调用 ARouter 的 inject 方法,完成参数注入
        ARouter.getInstance().inject(this);

        // 验证参数是否成功注入
        Log.d("RouteActivity", "Username: " + username); // 输出:xiaoduyyy
        Log.d("RouteActivity", "User Age: " + userAge);  // 输出:19
    }
}
2>获取返回结果

1. 设置目标 Activity 的返回数据:

  • 在目标 Activity 中,通过 setResult() 方法设置返回的数据,并在完成操作后调用 finish() 结束页面。

2. 调用 navigation() 传递请求码:

  • 在调用的页面(比如 MainActivity)中,通过 ARouternavigation() 方法传递请求码来启动目标 Activity

3.onActivityResult() 中接收返回的数据:

  • 在调用页面的 onActivityResult() 方法中接收目标页面返回的数据。

假设在 ResultActivity 中完成一些操作后,需要返回结果给调用页面:

@Route(path = "/test/ResultActivity")
public class ResultActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_result);

        // 假设在按钮点击时完成操作并返回结果
        findViewById(R.id.btn_finish).setOnClickListener(v -> {
            Intent data = new Intent();
            data.putExtra("result_key", "This is the result data");
            setResult(RESULT_OK, data);  // 设置返回结果
            finish();  // 结束页面
        });
    }
}

在调用页面启动目标页面并接收返回结果:

public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_CODE = 100;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 使用 ARouter 启动目标 Activity 并传递请求码
        findViewById(R.id.btn_start_activity).setOnClickListener(v -> 
            ARouter.getInstance().build("/test/ResultActivity").navigation(this, REQUEST_CODE));
    }

    // 重写 onActivityResult 接收返回结果
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE && resultCode == RESULT_OK && data != null) {
            String result = data.getStringExtra("result_key");
            Log.d("MainActivity", "Result from ResultActivity: " + result);
        }
    }
}
3>指定启动动画
ARouter.getInstance().build("/test/RouteActivity")
    .withTransition(R.anim.slide_in_right, R.anim.slide_out_left)
    .navigation();

R.anim.slide_in_rightR.anim.slide_out_left分别是进入和退出动画资源。

4>创建 Intent 对象而不立即跳转
Intent intent = ARouter.getInstance().build("/test/RouteActivity").getIntent(this);
startActivity(intent);

使用 ARouter 构建 Intent,然后可以在需要的时候再进行跳转。

总结

在现代 Android 应用开发中,路由框架的使用已成为一种趋势,尤其是在进行模块化开发时,ARouter 提供了一个高效、灵活的解决方案。通过 ARouter,开发者不仅能够简化页面间的导航和参数传递,还能增强应用的可维护性与扩展性。它的动态路由和服务管理功能使得开发过程更加高效,避免了传统开发中因模块间依赖过于紧密而导致的问题。

希望本篇博客能对大家有所帮助!

参考:

Android路由框架用法大全主要是映射页面跳转关系,根据路由表将页面请求分发到指定页面。显示Intent:项目庞大以后 - 掘金


已经到底啦!!


http://www.kler.cn/a/376180.html

相关文章:

  • 网络安全渗透实际案例
  • pandas——数据结构
  • C++设计模式结构型模式———桥接模式
  • Centos7搭建k8s集群
  • Android @JvmOverloads
  • 项目管理计算公式中的PV、EV、AC、CV、SV、CPI、SPI、ETC、EAC、BAC术语含义
  • 基于Matlab GUI的说话人识别测试平台
  • 一般无人机和FPV无人机的区别
  • 使用 MMDetection 实现 Pascal VOC 数据集的目标检测项目练习(二) ubuntu的下载安装
  • 【算法】奇数在偶数后、反转字符串中的单词
  • 仿真工具Modelsim和QuestaSim有什么区别?
  • 摄像机实时接入分析平台LiteAIServer视频智能分析软件诊断噪声检测
  • 利用Claude制作web小游戏(一):俄罗斯方块
  • 【Linux第七课--基础IO】内存级文件、重定向、缓冲区、文件系统、动态库静态库
  • JavaScript 进阶 - 第2天 (黑马笔记)
  • 数字后端零基础入门系列 | Innovus零基础LAB学习Day7
  • 必备!20道大模型面试问题详解(含答案)
  • Edge 浏览器插件开发:图片切割插件
  • 信息学科平台系统设计与实现:Spring Boot框架
  • 做等保二级备案需要准备哪些材料
  • Qt小bug —— QTableWidget排序后更新数据显示不全
  • 2024阿里云CTF Web writeup
  • Java 集合一口气讲完!(下)p\··/q
  • QNX 7.0.0开发总结
  • 【深度学习|地学应用】人工智能技术的发展历程与现状:探讨深度学习在遥感地学中的应用前景
  • 编程之路:蓝桥杯备赛指南