探索Android路由框架-ARouter之基本使用(一)(3.5w阅读量,详细,有用法,系列文章)
Android ARouter:最简单&粗暴(使用与原理)讲解(1.4w阅读量 详细,有条理)
组件是如何通信的?揭秘ARouter路由机制(详细)
利用ARouter实现组件间通信,解决子模块调用主模块问题(简单)
探索Android路由框架-ARouter之深挖源码(二)(跟第一篇同一作者,源码分析,可以多次学习)
ARouter基本使用与原理浅析(如题,对原理做一个简单分析)
ARouter官方项目地址
ARouter官方文档(很不错的官方文档,讲的很详细)
用到ARouter的模块都加上如下依赖:
android {
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments = [ AROUTER_MODULE_NAME : project.getName() ]
}
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
//ARouter
implementation "com.alibaba:arouter-api:1.5.0"
annotationProcessor "com.alibaba:arouter-compiler:1.2.2"
}
运行的时候报这个错误。
解决方法:在每个module(包括app)的build.gradle文件中加入以下内容
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments = [ AROUTER_MODULE_NAME : project.getName() ]
}
}
}
下载了GitHub的demo后,编译运行报出了以下错误:
Caused by: groovy.lang.MissingPropertyException: Could not get unknown property 'intellijPublishUsername' for task ':arouter-idea-plugin:publishPlugin' of type org.jetbrains.intellij.tasks.PublishTask.
解决方案:
settings.gradle里面include 了 arouter-idea-plugin,这个是 idea 插件的代码,publishPlugin 是用来发布插件的,自己源码编译的时候,不需要依赖这个 module。把它去掉或者注释掉后,项目就能正常编译了。
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
//ARouter初始化
ARouter.openLog(); // 打印日志
ARouter.openDebug();
ARouter.init(this);
}
}
注意:这里的路径需要注意的是至少需要有两级,/xx/xx
@Route(path = "/userCenter/UserActivity")
public class UserActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user);
}
}
public class ArouterActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_arouter);
findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 1. 应用内简单的跳转(通过URL跳转在'进阶用法'中)
ARouter.getInstance().build("/userCenter/UserActivity").navigation();
}
});
}
}
还有一个比较重要的问题是,如果你的项目有一个主module,那么你要想它正常跳转到指定module中的某个Activity,你的主Module一定要依赖想要跳转到的module,否则也是提示找不到路径,会报错:
ARounter报错"W/ARouter::: ARouter::There is no route match the path [/xxx/xxx], in group [xxx][ ]"
有三个module:app、base、module-test1
app和module-test1依赖base,app依赖module-test1
BaseConstant统一配置路径:
public class BaseConstant {
public static final String AROUTER_PATH_MODULE1_TEST1 = "/module1/Module1Test1Activity";
public static final String AROUTER_PATH_MODULE1_TEST2 = "/module1/Module1Test2Activity";
public static final String AROUTER_PATH_MODULE1_WEBVIEW = "/module1/TestWebViewActivity";
public static final String AROUTER_PATH_MODULE1_TEST_INTERCEPTOR = "/module1/TestInterceptorActivity";
}
//不携带参数跳转
findViewById(R.id.btn1).setOnClickListener(v -> {
// 1. 应用内简单的跳转
ARouter.getInstance()
.build(BaseConstant.AROUTER_PATH_MODULE1_TEST1)
.withTransition(R.anim.slide_in_bottom, R.anim.slide_out_bottom)
.navigation();
});
@Route(path = BaseConstant.AROUTER_PATH_MODULE1_TEST1)
public class Module1Test1Activity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_module1_test1);
}
}
// 携带参数跳转
findViewById(R.id.btn2).setOnClickListener(v -> {
ARouter.getInstance()
.build(BaseConstant.AROUTER_PATH_MODULE1_TEST2)
.withString("name", "android")
.withInt("age", 33)
.withParcelable("test", new Person("张三", 66))
.navigation();
});
@Route(path = BaseConstant.AROUTER_PATH_MODULE1_TEST2)
public class Module1Test2Activity extends AppCompatActivity {
@Autowired(name = "name")
String name;
@Autowired(name = "age")
int age;
@Autowired(name = "test")
Person person;
@Override
protected void onCreate(Bundle savedInstanceState) {
ARouter.getInstance().inject(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_module1_test2);
TextView tvShow = findViewById(R.id.tvShow);
tvShow.setText(name + ", " + age + "," + person.toString());
}
}
// 通过URL跳转
findViewById(R.id.btn3).setOnClickListener(v -> {
ARouter.getInstance()
.build(BaseConstant.AROUTER_PATH_MODULE1_WEBVIEW)
.withString("url", "file:///android_asset/scheme-test.html")
.navigation();
});
@Route(path = BaseConstant.AROUTER_PATH_MODULE1_WEBVIEW)
public class TestWebViewActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_web_view);
WebView webView=findViewById(R.id.webView);
webView.loadUrl(getIntent().getStringExtra("url"));
}
}
scheme-test.html
跳转测试
自定义Scheme[通常来说都是这样的]
arouter://m.aliyun.com/test/activity1
arouter://m.aliyun.com/test/activity2
arouter://m.aliyun.com/test/activity2?key1=value1
arouter://m.aliyun.com/test/activity3?name=alex&age=18&boy=true&high=180
App Links[防止被App屏蔽]
// 拦截器测试
findViewById(R.id.btn4).setOnClickListener(v -> {
ARouter.getInstance()
.build(BaseConstant.AROUTER_PATH_MODULE1_TEST_INTERCEPTOR)
.navigation(this, new NavCallback() {
@Override
public void onArrival(Postcard postcard) {
}
@Override
public void onInterrupt(Postcard postcard) {
LogUtils.e("被拦截了");
}
});
});
@Route(path = BaseConstant.AROUTER_PATH_MODULE1_TEST_INTERCEPTOR)
public class TestInterceptorActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_interceptor);
}
}
@Interceptor(priority = 7)
public class Test1Interceptor implements IInterceptor {
Context mContext;
@Override
public void process(Postcard postcard, InterceptorCallback callback) {
if (BaseConstant.AROUTER_PATH_MODULE1_TEST_INTERCEPTOR.equals(postcard.getPath())){
// 这里的弹窗仅做举例,代码写法不具有可参考价值
final AlertDialog.Builder ab = new AlertDialog.Builder(MainActivity.getActivity());
ab.setCancelable(false);
ab.setTitle("温馨提醒");
ab.setMessage("想要跳转到TestInterceptorActivity么?(触发了\"/inter/test1\"拦截器,拦截了本次跳转)");
ab.setNegativeButton("继续", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
callback.onContinue(postcard);
}
});
ab.setNeutralButton("算了", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
callback.onInterrupt(null);
}
});
ab.setPositiveButton("加点料", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
postcard.withString("extra", "我是在拦截器中附加的参数");
callback.onContinue(postcard);
}
});
MainLooper.runOnUiThread(new Runnable() {
@Override
public void run() {
ab.create().show();
}
});
}else {
callback.onContinue(postcard);
}
}
@Override
public void init(Context context) {
mContext = context;
LogUtils.e(Test1Interceptor.class.getName()+" has init.");
}
}