ARouter - Step by step完整代码上手(1)

骑猪看日落 2024-03-29 14:07 184阅读 0赞

1. ARouter干啥用?

ARouter是阿里开发的一个Android库,通过组件路由的方式帮助模块之间解耦依赖。

1.1 依赖如何产生

Android应用模块以activity和service为主,它们之间的调用以intent方式为主。虽然activity之间调用可以用过隐式依赖(AndroidManifest中声明intent-filter)的方式进行调用,这种方式主要是针对公共接口。应用内部的模块之间的依赖(通过显式intent调用)比公共接口数量要多很多。用intent需要知道package、class等信息,这样就产生了依赖关系。

1.2 带来的问题

第一,依赖可能会比较多,导致逻辑复杂,维护困难。尤其是规模比较大的复杂应用,模块之间的依赖数量会非常多,几十、几百都是可能的。
第二,一个应用的代码总是不停改动,就像人活着总是要新陈代谢一样。不可避免的要重构代码,修改报名、拆分(或合并)类等,这样被依赖方变了,依赖方也要相应的改变。
第三,实际工作中,不同的模块是由不同部门的团队维护的,比如账号管理模块、商品信息模块、推荐算法模块等,要把变更信息同步给不同团队,还要保证相关模块同时修改、上线,实际操作起来有难度。
这些问题对大型应用开发带来了不小的挑战,实际上会更加复杂,包括人员变动、业务调整等。

1.3 如何解决

  1. 给被依赖的模块设置一个字符串名称(例如: /activity/login),依赖方通过字符串名称调用。被依赖方无论怎么修改(字符串名称不变)都不影响调用,起到了解耦的作用。
  2. 需要有一个管理者(ARouter库)维护名称和模块(activity、service)之间的映射关系。
  3. 还提供了数据传递的方式,调用过程中传入和返回参数都可以支持。
  4. 调用过程中,通过拦截器模式,在调用过程中增加处理逻辑,更好的控制模块间依赖。
  5. 通过依赖注入和注解等方式,管理对应创建、方便代码实现。

2. 使用intent调用activity

1)MainActivity中有一个按钮,点击按钮通过intent调用OtherActivity。
2)这个主要是和使用ARouter做对比,一带而过直接看下一部分。

  1. // MainActivity.java
  2. package com.kaola.arouter_test;
  3. import androidx.appcompat.app.AppCompatActivity;
  4. import android.content.Intent;
  5. import android.os.Bundle;
  6. import android.view.View;
  7. import android.widget.Button;
  8. public class MainActivity extends AppCompatActivity {
  9. @Override
  10. protected void onCreate(Bundle savedInstanceState) {
  11. super.onCreate(savedInstanceState);
  12. setContentView(R.layout.activity_main);
  13. Button btn = findViewById(R.id.btn_start);
  14. btn.setOnClickListener((View v) -> {
  15. Intent i = new Intent(MainActivity.this, OtherActivity.class);
  16. startActivity(i);
  17. });
  18. findViewById(R.id.btn_finish).setOnClickListener((View v) -> {
  19. finish();
  20. });
  21. }
  22. }
  23. <!--activity_main.xml-->
  24. <?xml version="1.0" encoding="utf-8"?>
  25. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  26. xmlns:app="http://schemas.android.com/apk/res-auto"
  27. xmlns:tools="http://schemas.android.com/tools"
  28. android:layout_width="match_parent"
  29. android:layout_height="match_parent"
  30. tools:context=".MainActivity">
  31. <TextView
  32. android:id="@+id/tv_main"
  33. android:layout_width="wrap_content"
  34. android:layout_height="wrap_content"
  35. android:text="Main activity!"
  36. app:layout_constraintBottom_toBottomOf="parent"
  37. app:layout_constraintLeft_toLeftOf="parent"
  38. app:layout_constraintRight_toRightOf="parent"
  39. app:layout_constraintTop_toTopOf="parent" />
  40. <Button
  41. android:id="@+id/btn_start"
  42. android:layout_width="100dp"
  43. android:layout_height="50dp"
  44. android:layout_margin="20dp"
  45. android:text="start"
  46. app:layout_constraintTop_toBottomOf="@id/tv_main"
  47. app:layout_constraintLeft_toLeftOf="parent"
  48. app:layout_constraintRight_toRightOf="parent"
  49. />
  50. <Button
  51. android:id="@+id/btn_finish"
  52. android:layout_width="100dp"
  53. android:layout_height="50dp"
  54. android:layout_margin="20dp"
  55. android:text="finish"
  56. app:layout_constraintTop_toBottomOf="@id/btn_start"
  57. app:layout_constraintLeft_toLeftOf="parent"
  58. app:layout_constraintRight_toRightOf="parent"
  59. />
  60. </androidx.constraintlayout.widget.ConstraintLayout>
  61. // OtherActivity.java
  62. package com.kaola.arouter_test;
  63. import android.os.Bundle;
  64. import android.view.View;
  65. import android.widget.Button;
  66. import androidx.appcompat.app.AppCompatActivity;
  67. public class OtherActivity extends AppCompatActivity {
  68. @Override
  69. protected void onCreate(Bundle savedInstanceState) {
  70. super.onCreate(savedInstanceState);
  71. setContentView(R.layout.activity_other);
  72. Button btn = findViewById(R.id.btn_other);
  73. btn.setOnClickListener((View v) -> {
  74. finish();
  75. });
  76. }
  77. }
  78. <!--activity_other.xml-->
  79. <?xml version="1.0" encoding="utf-8"?>
  80. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  81. xmlns:app="http://schemas.android.com/apk/res-auto"
  82. xmlns:tools="http://schemas.android.com/tools"
  83. android:layout_width="match_parent"
  84. android:layout_height="match_parent"
  85. tools:context=".MainActivity">
  86. <TextView
  87. android:id="@+id/tv_other"
  88. android:layout_width="wrap_content"
  89. android:layout_height="wrap_content"
  90. android:text="Other activity!"
  91. app:layout_constraintBottom_toBottomOf="parent"
  92. app:layout_constraintLeft_toLeftOf="parent"
  93. app:layout_constraintRight_toRightOf="parent"
  94. app:layout_constraintTop_toTopOf="parent" />
  95. <Button
  96. android:id="@+id/btn_other"
  97. android:layout_width="100dp"
  98. android:layout_height="50dp"
  99. android:layout_margin="20dp"
  100. android:text="finish"
  101. app:layout_constraintTop_toBottomOf="@id/tv_other"
  102. app:layout_constraintLeft_toLeftOf="parent"
  103. app:layout_constraintRight_toRightOf="parent"
  104. />
  105. </androidx.constraintlayout.widget.ConstraintLayout>
  106. <!--AndroidManifest.xml-->
  107. <?xml version="1.0" encoding="utf-8"?>
  108. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  109. package="com.kaola.arouter_test">
  110. <application
  111. android:allowBackup="true"
  112. android:icon="@mipmap/ic_launcher"
  113. android:label="@string/app_name"
  114. android:roundIcon="@mipmap/ic_launcher_round"
  115. android:supportsRtl="true"
  116. android:theme="@style/Theme.Arouter_test">
  117. <activity
  118. android:name=".MainActivity"
  119. android:exported="true">
  120. <intent-filter>
  121. <action android:name="android.intent.action.MAIN" />
  122. <category android:name="android.intent.category.LAUNCHER" />
  123. </intent-filter>
  124. </activity>
  125. <activity android:name=".OtherActivity" android:exported="true"/>
  126. </application>
  127. </manifest>

3. 通过ARoute调用activity

3.1 主要修改说明

1)在build.gradle中引入ARoute依赖。
2)自定义一个Application,用于初始化ARouter。
ARouter是一个基础服务的角色,所以需要在应用中尽早启动,才能为其他模块提供服务。而且生命周期要长久,在Application中初始化比较合适。
3)在AndroidManifest.xml中指定自定义的Application。
4)OtherActivity是被依赖方、被调用方:
4.1 )通过@Route注解指定path(名称):@Route(path=“/activity/other”),路径至少要2级。
4.2)在onCreate()中通过ARouter注入:ARouter.getInstance().inject(this)。
4.3)通过@Autowired注解(面熟吗?)引用传入的参数: @Autowired(name = “msg”)。
5)MainActivity是调用方:
5.1)通过ARouter调用OtherActivity
ARouter.getInstance().build(“/activity/other”) // OtherActivity中设置的路径名
.withString(“msg”, “Tesla price-off a…gain~”) // 传递给OtherActivity的参数
.navigation(); // 启动activity

3.2 build.gradle修改

  1. android {
  2. defaultConfig {
  3. // 其他内容忽略
  4. // arouter
  5. javaCompileOptions {
  6. annotationProcessorOptions {
  7. arguments = [AROUTER_MODULE_NAME: project.getName()]
  8. }
  9. }
  10. }
  11. }
  12. dependencies {
  13. // 其他不相干内容忽略
  14. // arouter
  15. implementation 'com.alibaba:arouter-api:1.5.2'
  16. annotationProcessor 'com.alibaba:arouter-compiler:1.5.2'
  17. }

3.3 自定义Application

  1. package com.kaola.arouter_test;
  2. import android.app.Application;
  3. import com.alibaba.android.arouter.launcher.ARouter;
  4. public class MyApplication extends Application {
  5. @Override
  6. public void onCreate() {
  7. super.onCreate();
  8. // 初始化ARouter
  9. ARouter.openLog();
  10. ARouter.openDebug();
  11. ARouter.init(this);
  12. }
  13. }

3.4 修改AndroidManifest.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.kaola.arouter_test">
  4. <application
  5. android:name=".MyApplication" <--- 自定义的Application
  6. android:allowBackup="true"
  7. android:icon="@mipmap/ic_launcher"
  8. android:label="@string/app_name"
  9. android:roundIcon="@mipmap/ic_launcher_round"
  10. android:supportsRtl="true"
  11. android:theme="@style/Theme.Arouter_test">
  12. <activity
  13. android:name=".MainActivity"
  14. android:exported="true">
  15. <intent-filter>
  16. <action android:name="android.intent.action.MAIN" />
  17. <category android:name="android.intent.category.LAUNCHER" />
  18. </intent-filter>
  19. </activity>
  20. <activity android:name=".OtherActivity" android:exported="true"/>
  21. </application>
  22. </manifest>

3.5 修改OtherActivity.java

  1. package com.kaola.arouter_test;
  2. import android.os.Bundle;
  3. import android.view.View;
  4. import android.widget.Button;
  5. import android.widget.TextView;
  6. import androidx.appcompat.app.AppCompatActivity;
  7. import com.alibaba.android.arouter.facade.annotation.Autowired;
  8. import com.alibaba.android.arouter.facade.annotation.Route;
  9. import com.alibaba.android.arouter.launcher.ARouter;
  10. @Route(path="/activity/other") // 1. 通过@Route注解声明调用路径
  11. public class OtherActivity extends AppCompatActivity {
  12. @Autowired(name = "msg") // 2. 通过@Autowired注解,注入传入的变量
  13. String message;
  14. @Autowired(name = "price_off")
  15. int off;
  16. @Override
  17. protected void onCreate(Bundle savedInstanceState) {
  18. super.onCreate(savedInstanceState);
  19. setContentView(R.layout.activity_other);
  20. ARouter.getInstance().inject(this); // 3. 把OtherActivity注入到ARoute框架中,让其他模块可以调用
  21. Button btn = findViewById(R.id.btn_other);
  22. btn.setOnClickListener((View v) -> {
  23. finish();
  24. });
  25. TextView text = findViewById(R.id.tv_other);
  26. text.setText("Other activity get: msg:" + message + ", by " + off);
  27. }
  28. }

3.6 修改MainActivity.java

  1. package com.kaola.arouter_test;
  2. import androidx.appcompat.app.AppCompatActivity;
  3. import android.content.Intent;
  4. import android.os.Bundle;
  5. import android.view.View;
  6. import android.widget.Button;
  7. import com.alibaba.android.arouter.launcher.ARouter;
  8. public class MainActivity extends AppCompatActivity {
  9. @Override
  10. protected void onCreate(Bundle savedInstanceState) {
  11. super.onCreate(savedInstanceState);
  12. setContentView(R.layout.activity_main);
  13. Button btn = findViewById(R.id.btn_start);
  14. btn.setOnClickListener((View v) -> {
  15. // Intent i = new Intent(MainActivity.this, OtherActivity.class);
  16. // startActivity(i);
  17. // 上面是普通的intent方式调用,下面是通过ARouter来调用,不依赖任何报名、类名
  18. ARouter.getInstance().build("/activity/other")
  19. .withString("msg", "Tesla price-off a...gain~")
  20. .withInt("price_off", 50000)
  21. .navigation();
  22. });
  23. findViewById(R.id.btn_finish).setOnClickListener((View v) -> {
  24. finish();
  25. });
  26. }
  27. }

到这里我们了解了ARouter引入的背景、要解决的问题,对在实际开发中如何使用ARouter有了一个初步的认识。
后续文章中会说明ARouter的详细用法,以及关联的原理知识。

发表评论

表情:
评论列表 (有 0 条评论,184人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Git Step by Step (1):Git 简介

    由于工作的需要,代码版本控制工具要从Perforce换成Git。说实话,刚开始真的很不适应,要从一个可以很好的支持用户界面的工具转到一个命令行工具,而且Git中有几百个命令,一

    相关 Step by Step into Spring (事务)

    1.事务 在与数据库相关的应用中,事务是一个必不可少的话题。如一些常见的事务概念:脏读、可重复读、幻读等这些事应该需要了解的。本文不是再次介绍数据库相关的事务原理,而是准