12.2 Activity消息路由
在Android开发中,常遇到多个Activity间的相互通信和调用,这样会导致Acticity间的横向依赖。
Activity间的相互通信和调用主要是通过调用startActivity()函数实现的,使用startActivity()的缺点是需要被通知或调用的那个Activity类已经存在,否则无法通过编译,但是在实际的开发工作中,这往往是无法得到满足的。
为了解决此问题,需要设计和实现一个路由框架,实现不同Activity间的解耦。
12.2.1 设计思路
实现一个Activity路由类,由这个类实现Activity间的路由,各Activity间不直接联系,由路由类作为中间件,实现各Activity间的联系。
目前大多数路由方式都是采用URL的方式实现的,在此利用类的反射机制实现此功能,实现方式相对简单。
12.2.2 具体实现
代码如下:
public class ActivityRouter {
//每创建一个Activity,就在此定义一个字符串,记录此Activity的类名
public static final String SECOND_ACTIVITY = "com.example.myapplication.SecondActivity";
public static final String THREE_ACTIVITY = "com.example.myapplication.ThreeActivity";
public static final String FOUR_ACTIVITY = "com.example. myapplication.FourActivity";
// 传递Activity消息的函数,activityContext表示调用startActivity的Activity,activityName表示被调用或被通知的Activity的类名字符串
public static boolean ActivityRouter(Intent intent, Context activityContext, final String activityName){
if(intent == null || activityContext == null || activityName == null){
return false;
}
Class<?> activityClass = null;
try {
//通过类名字符串,找到相应的类
activityClass = Class.forName(activityName);
if(activityClass != null){
intent.setClass(activityContext, activityClass);
}
}catch (Exception e){
e.printStackTrace();
return false;
}
return true;
}
}
使用示例:
//Activity间不传值时的情况
Intent intent = new Intent();
if (ActivityRouter.ActivityRouter(intent, MainActivity.this,ActivityRouter.SECOND_ACTIVITY)) {
startActivity(intent);
}
//Activity间传值时的情况
Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putString("keyString", "string");
bundle.putInt("keyInt", 100);
intent.putExtras(bundle);
if (ActivityRouter.ActivityRouter(intent, MainActivity.this,ActivityRouter.THREE_ACTIVITY)) {
startActivity(intent);
}
//Activity间传值,且主调Activity需要接收被调Activity返回值的情况
Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putString("keyString", "hello");
bundle.putInt("keyInt", 400);
intent.putExtras(bundle);
if (ActivityRouter.ActivityRouter(intent, MainActivity.this,ActivityRouter.FOUR_ACTIVITY)) {
startActivityForResult(intent, REQUESTCODE);
}