官方使用说明
官网
https://github.com/alibaba/ARouter/blob/master/README_CN.md
阿里巴巴自研路由框架,主要解决组件间、模块间的 界面跳转 问题
典型应用
- 从外部URL映射到内部页面,以及参数传递与解析
- 跨模块页面跳转,模块间解耦
- 拦截跳转过程,处理登陆、埋点等逻辑
- 跨模块API调用,通过控制反转来做组件解耦
基础功能
1, 添加依赖和配置
android {
defaultConfig {
...
//每一个用的build.都要加
javaCompileOptions {
annotationProcessorOptions {
arguments = [AROUTER_MODULE_NAME: project.getName()]
}
}
}
}
配置
dependencies {
implementation 'com.alibaba:arouter-api:1.5.1'
annotationProcessor 'com.alibaba:arouter-compiler:1.5.1'
...
}
注: 未配置configurations出现的错误
错误: ARouter::Compiler An exception is encountered, [These no module name, at 'build.gradle', like :
2 初始化sdk
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
ARouter.openLog(); // 打印日志
ARouter.openDebug(); // 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)
ARouter.init(this); // 尽可能早,推荐在Application中初始化
}
}
在清单 文件中设置name属性.
2,添加注解-配置路径(无参)
添加注释(Add annotations)
目标页面添加@Route注解
path:模板页面路径,必须以斜杠开头两级以上路径
group:页面组,默认为module名作为命名
// 在支持路由的页面上添加注解(必选)
// 这里的路径需要注意的是至少需要有两级,/xx/xx
@Route(path = "/Xxx_module/XxxActivity")
public class XxxActivity extend Activity {
...
}
/**
* 配置路径
*/
@Route( path = "/shop/main2")
public class Main2Activity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
}
}
跳转页面(Initiate the routing)
//Activity跳转
ARouter.getInstance().build("/Xxx_module/XxxActivity").navigation();
//Fragment引入
Fragment fragment = (Fragment) ARouter.getInstance().build("/Xxx_module/XxxFragment").navigation();
3. 跳转并携带参数
跳转页面携带参数(Initiate the routing Jump with parameters)
参数携带已withXXX()方法进行对应数据类型参数携带
特别说明:withObject()不可直接使用:如何使用见向下继续看
ARouter.getInstance().build("/test/1")
.withString("key3", "888")
.navigation();
3.1 携带参数withObject(Initiate the routing Jump with parameters)
在页面跳转传递自定义对象参数时,我们要进行序列号服务的创建。
好-。-如何创建公共的序列化服务,只需要创建一次,作为工具类。
1.实现ARouter接口SerializationService
2.完成对应方法实现,我们可以使用JSON 或 GSON来进行方法实现,进行对象和字符串的转换
@Route(path = "/service/gson")
public class GosnServiceImp implements SerializationService {
private Gson gson;
@Override
public <T> T json2Object(String input, Class<T> clazz) {
return gson.fromJson(input, clazz);
}
@Override
public String object2Json(Object instance) {
return gson.toJson(instance);
}
@Override
public <T> T parseObject(String input, Type clazz) {
return gson.fromJson(input, clazz);
}
@Override
public void init(Context context) {
gson = new Gson();
}
}
4,接收参数方
@Route(path = "/app/main3")
public class Main3Activity extends AppCompatActivity {
@Autowired
String key3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
//注入
ARouter.getInstance().inject(this);
Toast.makeText(this, key3, Toast.LENGTH_SHORT).show();
}
}
5 组件之间的跳转
ARouter.getInstance().build("/news/main").navigation();
链接方法是一样的.
只是要跳转过去的模块必须是library加入到当前的项目中的.
如果用了calces管理,则可以直接跳转.
如果不是,则手动添加library.
注意的问题
如果用calces管理,清单文件会合并,那么类名相同的则会有冲突.
6 对象的传递
ARouter.getInstance().build("/app/main3")
.withString("key3", "888")
.withObject("test",new Test("hehe","haha")) //对象
.navigation();
6.1 主要是实现一个接口
@Route(path = "/transerver/gson")
public class JSonBean implements SerializationService {
private Gson gson;
@Override
public <T> T json2Object(String input, Class<T> clazz) {
return gson.fromJson(input,clazz);
}
@Override
public String object2Json(Object instance) {
return gson.toJson(instance);
}
@Override
public <T> T parseObject(String input, Type clazz) {
return gson.fromJson(input,clazz);
}
@Override
public void init(Context context) {
gson = new Gson();
}
}
此接口的路径随意. 它的主要目的是把字符串和对象直接相互转换.
它提供框架,我们实现逻辑.比如可以用Gson 也可以用FastJson.
7, 用路由动态添加fragment
创建fragment
@Route(path = "/fragment/blank")
public class BlankFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_blank, container, false);
}
}
使用路由查找
public void btn3(View view) {
Fragment fragment = (Fragment) ARouter.getInstance().build("/fragment/blank").navigation();
getSupportFragmentManager().beginTransaction().add(R.id.ll,fragment).commit();
8 拦截器的实现
// 比较经典的应用就是在跳转过程中处理登陆事件,这样就不需要在目标页重复做登陆检查
// 拦截器会在跳转之间执行,多个拦截器会按优先级顺序依次执行
@Interceptor(priority = 8, name = "测试用拦截器")
public class TestInterceptor implements IInterceptor {
@Override
public void process(Postcard postcard, InterceptorCallback callback) {
...
callback.onContinue(postcard); // 处理完成,交还控制权
// callback.onInterrupt(new RuntimeException("我觉得有点异常")); // 觉得有问题,中断路由流程
// 以上两种至少需要调用其中一种,否则不会继续路由
}
@Override
public void init(Context context) {
// 拦截器的初始化,会在sdk初始化的时候调用该方法,仅会调用一次
}
}
应用:
ARouter.getInstance().build("/news/main").navigation(this, new NavigationCallback() {
@Override
public void onFound(Postcard postcard) {
}
@Override
public void onLost(Postcard postcard) {
}
@Override
public void onArrival(Postcard postcard) {
}
//子线程
@Override
public void onInterrupt(Postcard postcard) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "拦截了", Toast.LENGTH_SHORT).show();
}
});
}
});
ARouter 和 Calces结合使用
特别注意事项:
如果是接着用calces来做项目的话, Main2Activity文件可能提示找不到.
这要在修改两个地方,一个是.
app {
applicationName '.App'
modules ':news',':shop'
}
给启动添加一个app. 用来初始化ARouter.
另一个是:如果清单文件没有Main2Activity 需要在,project的目录下的src的文件夹下的清单文件中添加.而不是calces中的文件中添加.
把一个项目变成一个module
1)在app的里面的build.gradle里面把
apply plugin: ‘com.android.application’
替换成如下
apply plugin: ‘com.android.library’
2)注视掉build.gradle文件里面的applicationId
3)app的AndroidManifest文件中MainActivity的注释掉,因为一个App 不能存在2个程序入口,否则在桌面也会有2个图标
4)在其它项目用通过导入module的方式导入这个module
本身的app也要变从module
apply plugin: 'calces.modules'
appConfig {
//调试开关,控制所有app能不能独立运行
debugEnable true
apps {
//把app也改成moudle .然后id和name都不能少.
//可以少name 报错看看
app {
applicationId "com.fenghongzhang.feng2"
applicationName ".App"
modules ':shop'
}
}
//所有组件
modules {
//注意事项:
//如果设定了applicationId 则要原来的applicationId删除相关 否则报错
//isRunAlone 必须是false 才能跳转.因为false就是moudle了
shop {
name ':shop'
applicationId "com.fenghongzhang.shop"
mainActivity ".MainActivity"
isRunAlone true
}
}
}