引言
在我们使用组件化的时候,活动并不在一个模块当中,但是毕竟是一个程序我们需要在不同的模块之间进行跳转,我们会首先想到在需要进行通信的模块下都添加相应的依赖就可以解决这个问题,但这样无疑增加了各个组件之间的耦合性。因此会想到如何能够在不添加依赖的情况下还行进行各个组件之间的通信,接下来就认识一个强大的工具——ARouter
路由认知
路由框架是用于管理应用程序中不同组件(如页面、活动、模块等)之间导航和通信的工具。它通常提供了一种简化的方式来处理路由、参数传递和组件间的调用,使得开发者能够更加方便地管理应用的结构和导航。
他就像是邮局,将寄信人与接收人联系起来,接下来就来看看它是如何实现的。
自定义路由
这里是为了让大家更好的理解ARouter。路由是为了实现各个组件之间的通信,不就属于上面的基础组件层,我们在基础组件层新建一个模块名为librouter,此模块下新建一个Router类去实现ARouter的功能。
我们要保证程序当中只有一个路由,即使路由为单例模式,因此采用单例模式进行创建:
public Router() {
}
public final static class Holder {static Router INSTANCE = new Router();
}
public static Router getInstance() {return Holder.INSTANCE;
}
Router的作用就是管理所有的类,可以协调使用这些类,如何进行存储。不同的包名下有不同的多个Activity:
static final Map<String, Map<String, Class<?>>> groupMap = new HashMap<>();
final Map<String, Class<?>> routeMap = new HashMap<>();
首先就会想到如何进行存储这些不同的类:
public void register(String path, Class<?> clz) {//我们所要存储的就是不同的Activity与相应的路径与包名,包名是包括在路径之下的,因此所要传进的就是一个字符串,一个class,我们要将路径下的包名解析出来所以使用'/',在进行注册的时候://Router.getInstance().register("/main/MainActivity", MainActivity.class);String[] strArray = path.split("/");if (strArray.length > 2) {//我们取出包名,判断这个包名有没有注册过,当注册过的时候我们就将其取出来,否则就创建出一个新的,将其放到groupMap当中,最后将其添加到routeMap当中,即完成注册String groupName = strArray[1];Map<String, Class<?>> routeMap = null;if (groupMap.containsKey(groupName)) {routeMap = groupMap.get(groupName);} else {routeMap = new HashMap<>();groupMap.put(groupName, routeMap);}routeMap.put(groupName, clz);}
}
注册类的方法我们就写完了,接下来就是给所有的活动进行注册了:
在App下新建一个MyApplication,我们想要随程序的启动就进行注册,因此将注册方法写道onCreate当中,并将其添加到AndroidManifest.XML文件当中:
public class MyApplication extends Application {@Overridepublic void onCreate() {super.onCreate();Log.d("TestTest", "我进行了注册");Router.getInstance().register("/main/MainActivity", MainActivity.class);Router.getInstance().register("/loginUp/LoginUpActivity", LoginUpActivity.class);}
}
这样就注册完毕了,我们做了这么多的准备不就是为了进行不同组件之间活动的跳转吗,看看跳转活动如何写:
public void startActivity(Activity activity, String path) {String[] strArray = path.split("/");if (strArray.length > 2) {String groupName = strArray[1];String routeName = path;Map<String, Class<?>> group = null;if (groupMap.containsKey(groupName)) {group = groupMap.get(groupName);}if (group != null && group.containsKey(routeName)) {Class<?> clz = group.get(routeName);activity.startActivity(new Intent(activity, clz));}}
}
对于前面的代码就不做过多的解释了与上面注册的代码是一样的,后面的代码也很好理解,就大致说一下思路吧,我们根据传进来的路径名即为我们所要开启的活动的路径,先判断我们有没有注册这个包名,根据包名取出对应的此包下的活动集合,在判断是不是有此路径的活动,当有的时候我们就可以取出对应的活动,从而进行活动的跳转。
Router.getInstance().startActivity(LoginUpActivity.this, "/main/MainActivity");
在登录的组件当中无需进行主活动的依赖就可以实现跳转了。
使用路由——ARouter
通过上面自定义实现了路由框架,你对ARouter’的实现已经有了大致的了解,接下来就正式的认识路由插件——ARouter。
首先需要对其添加依赖:
implementation("com.alibaba:arouter-api:1.5.2")
annotationProcessor("com.alibaba:arouter-compiler:1.5.2")
我们第一个还想到的是进行注册,此时我们只需要给活动添加注解即可完成注册:
这段代码是 Gradle 构建配置中的一部分,用于设置 Java 编译选项,特别是针对注解处理器(Annotation Processors)的配置。在这个特定的代码段中,配置了传递给注解处理器的参数。以下是详细解释:
javaCompileOptions
javaCompileOptions
是一个配置块,用于定义 Java 编译过程中的选项。这些选项包括编译时使用的 Java 版本、注解处理器的配置等。
annotationProcessorOptions
annotationProcessorOptions
是javaCompileOptions
内的配置块,专门用于设置注解处理器的选项。在这个配置块中,你可以指定注解处理器需要的参数、处理器的类路径等。
arguments
arguments
是annotationProcessorOptions
内的属性,它允许你为注解处理器传递一组键值对参数。这些参数可以在注解处理器的执行过程中被读取和使用。
AROUTER_MODULE_NAME: project.getName()
在这个例子中,
arguments
属性被设置为一个包含单个键值对的 Map。键是AROUTER_MODULE_NAME
,值是通过调用project.getName()
方法获取的当前项目的名称。
AROUTER_MODULE_NAME
是注解处理器期望的一个参数键,它用于接收传递给它的值。project.getName()
是 Gradle API 提供的方法,返回当前项目的名称。这个名称通常对应于项目在多模块构建中的路径,例如:app
或:library:module1
。总结
这段配置的目的是为 ARouter的注解处理器提供项目的名称作为参数。这样,ARouter 可以根据项目的名称来执行特定的逻辑,比如生成路由表时区分不同模块。这种配置方式使得注解处理器能够更加灵活地适应不同的项目和模块。
在总体的gradle.propertise文件当中添加:
我们进行了注册以及配置的相关操作,接下来与上面我们自定义的一样需要对其初始化:
public class MyApplication extends Application {//ARouter调用开关private boolean isDebugARouter=true;@Overridepublic void onCreate() {super.onCreate();if (isDebugARouter) {// 打印日志ARouter.openLog();// 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)ARouter.openDebug();}ARouter.init(this);}
}
使用他进行跳转操作吧:
ARouter.getInstance().build("/main/MainActivity").navigation();
接下来运行程序就可以从登陆界面跳转到主活动界面了。
当然,我们不单单要实现不同组件之间活动的跳转,还要传对应的参数,ARouter使用的是建造者的方式,因此我们只需要对其进行build即可:
ARouter.getInstance().build("/main/MainActivity").withString("key1","我是传过来的字符串").withBoolean("key2", false)//对user进行序列化,此时要么进行强转为序列化,要么在user类当中implements Serializable去实现序列化.withSerializable("key3", new user("海绵宝宝", 5))//navigation() 方法用于根据指定的路由路径启动目标 Activity 或传递参数。它是链式调用的最后一个环节,用于触发实际的导航行为。.navigation();
此时就发送完毕了,要如何进行接收呢?
@Route(path = "/main/MainActivity")
public class MainActivity extends AppCompatActivity {@Autowired(name = "key1")public String name;@Autowired(name = "key3")public user user;@Overrideprotected void onCreate(Bundle savedInstanceState) {......//inject(this); 是 ARouter 提供的一个方法,用于将通过路由传递的参数注入到当前对象中ARouter.getInstance().inject(this);Log.d("TestTest", name + "");if (user != null) {Log.d("TestTest", user.getName() + user.getAge());}}
}
查看打印日志:
此时就将数据传输过来了!
文章到这里就结束了!