我们平时Activity的跳转用的是下面的代码
Intent intent = new Intent(activity, SecondActivity.class);
activity.startActivity(intent);
但是在组件化中各个module都是可插拔的,可能上面的SecondActivity所在的module没有被依赖,那么上面的代码就会报红。为了解决这个问题,我们可以用一个映射表来存储路径key和对应的Activity,这么一来就不会报红,我们可以通过startActivity(activity, "/shop/ShopActivity")这种方式来尝试跳转,这样就算主工程没有添加shop这个module的依赖也不会报错,只会吐司提示没有可跳转的页面。
Map<String, Class<? extends Activity>> routers = new HashMap<>();
public static void startActivity(Activity activity, String path){
if(!routers.containsKey(path)){
Toast.makeText(activity, "没有可跳转的页面", Toast.LENGTH_SHORT).show();
return;
}
Intent intent = new Intent(activity, routers.get(path));
activity.startActivity(intent);
}
现在的问题就是怎么将Activity的class放入映射表routers中。
我们可以给需要跳转的Activity用注解标注,并通过注解传入自定义的path做为映射表的key。
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface XRoute {
String value();//路径
}
@XRoute("/shop/ShopActivity")
public class ShopActivity extends AppCompatActivity {
...
}
然后写一个APT(注解处理器)来处理每个module下的注解类。可以利用编译时技术生成代码,为每个module生成一个注册类,注册类所需注册用的key,value我们可以遍历module下的注解类得到。这个注册类需要实现一个统一规范接口。这么一来我们就能通过包管理器获取到包下的所有类,进而通过这个接口规范筛选出他们,然后通过java反射实例化,并且运行他们的注册方法,这么一来我们需要的路由表就能动态生成。
下面是具体实现的代码
XRouter: 手写路由框架
|