首页 > 编程知识 正文

arouter原理 简书,Arouter原理

时间:2023-05-06 17:53:27 阅读:227986 作者:4484

Paste_Image.png

 

上图是目前比较普遍使用的Android APP技术架构,往往是在一个界面中存在大量的业务逻辑,而业务逻辑中充斥着各种网络请求、数据操作等行为,整个项目中也没有模块的概念,只有简单的以业务逻辑划分的文件夹,并且业务之间也是直接相互调用、高度耦合在一起的;

 

Paste_Image.png

 

上图单一工程模型下的业务关系,总的来说就是:你中有我,我中有你,相互依赖,无法分离。
然而随着产品的迭代,业务越来越复杂,随之带来的是项目结构复杂度的极度增加,此时我们会面临如下几个问题:

1、实际业务变化非常快,但是单一工程的业务模块耦合度太高,牵一发而动全身;
2、对工程所做的任何修改都必须要编译整个工程;
3、功能测试和系统测试每次都要进行;
4、团队协同开发存在较多的冲突.不得不花费更多的时间去沟通和协调,并且在开发过程中,任何一位成员没办法专注于自己的功能点,影响开发效率;
5、不能灵活的对业务模块进行配置和组装;

 

Paste_Image.png

 

上图是组件化工程模型

Paste_Image.png

 

上图是组件化开发在Android studio里面的目录工程结构

Paste_Image.png

 

这是组件化工程模型下的业务关系,业务之间将不再直接引用和依赖,而是通过“路由”这样一个中转站间接产生联系,我们今天要讲的就是这个路由。

路由怎么工作呢?
比如上面图中,每个业务分别在不同的moudle中,分别有ActivityA、ActivityB、ActivityC、ActivityD。
假如ActivityA想跳转到ActivityB怎么实现呢?通常跳转是这么写的:

 

Intent intent = new Intent(this,ActivityB.class);startActivity(intent);

但是现在业务A和业务B在不同的moudle中,A业务中没法 import ActivityB,因为A和B是相互独立,没有依赖的。
路由做的事情就是在不用引导类的情况下实现这一跳转。

现在比较流行的路由有两个ActivityRouter、ARouter
ActivityRouter是个人项目
ARouter是阿里的项目
我们选择阿里的Arouter好一点

先看下ARouter的使用方法

 

android { defaultConfig { ... javaCompileOptions { annotationProcessorOptions { arguments = [ moduleName : project.getName() ] } } }}dependencies { // 替换成最新版本, 需要注意的是api // 要与compiler匹配使用,均使用最新版可以保证兼容 compile 'com.alibaba:arouter-api:x.x.x' annotationProcessor 'com.alibaba:arouter-compiler:x.x.x' ...}

然后在Application中初始化

 

if (isDebug()) { // 这两行必须写在init之前,否则这些配置在init过程中将无效 ARouter.openLog(); // 打印日志 ARouter.openDebug(); // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)}ARouter.init(mApplication); // 尽可能早,推荐在Application中初始化

接着使用注解标记要跳转的Activity

 

@Route(path = "/module_b/activity_b")public class ActivityB extend Activity { ...}

然后在ActivityA中这样跳转到ActivityB

 

ARouter.getInstance().build("/module_b/activity_b").navigation();

这样就完成了不同业务之间的跳转,是不是超级简单?

当然跳转一般都会传参数

 

// 2. 跳转并携带参数ARouter.getInstance().build("/module_b/activity_b") .withLong("key1", 666L) .withString("key3", "888") .withObject("key4", new Test("Jack", "Rose")) .navigation();

在ActivityB中获取参数有两种方式,一种是普通Activity那样getIntent().getXXX
加一种是使用@Autowired注解的方式

 

@Route(path = "/test/activity")public class Test1Activity extends Activity { @Autowired public String name; @Autowired int age; @Autowired(name = "girl") // 通过name来映射URL中的不同参数 boolean boy; @Autowired TestObj obj; // 支持解析自定义对象,URL中使用json传递 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ARouter.getInstance().inject(this); // ARouter会自动对字段进行赋值,无需主动获取 Log.d("param", name + age + boy); }}

还有一种情况,业务A是要使用业务C中的某个服务或者说某种功能,并不是想跳转Activity

这种情况下就要使用到IProvider

 

// 声明接口,其他组件通过接口来调用服务public interface HelloService extends IProvider { String sayHello(String name);}// 实现接口@Route(path = "/service/hello", name = "测试服务")public class HelloServiceImpl implements HelloService { @Override public String sayHello(String name) { return "hello, " + name; } @Override public void init(Context context) { }}

干净的自行车的接口放在base module中,接口的实现放在具体功能实现的module中。
然后在要使用这一服务的module中这样使用:

 

HelloService helloService = (HelloService) ARouter.getInstance().build("/service/hello").navigation(); helloService.sayHello("Vergil");

这样就实现了调用其他业务服务

还有还可能通过ARouter获取其他业务模块的Fragment:

 

// 获取FragmentFragment fragment = (Fragment) ARouter.getInstance().build("/test/fragment").navigation();

下面是一些特殊用法:

 

// 构建标准的路由请求,startActivityForResult// navigation的第一个参数必须是Activity,第二个参数则是RequestCodeARouter.getInstance().build("/home/main", "ap").navigation(this, 5);

上面是从Activity调startActivityForResult 但是Arouter没有API支持从fragment调startActivityForResult
这种情况要怎么办呢?

可以这样做

 

Postcard postcard = ARouter.getInstance().build("/module2/activity"); LogisticsCenter.completion(postcard); Class<?> destination = postcard.getDestination();

这里得到的destination类就是我们要跳转的类,这样fragment的startActivityForResult就好办了

 

Intent intent = new Intent(getContext(),destination);startActivityForResult(intent,requestCode);



 
 

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。