【简单实现组件之间跳转】
- 基础公共组件中的路由表以key value的映射集合形式存放在堆内存里,
- 在Application里往map集合中注册需要的类,
- 需要跳转时通过key获取value即获取目的类即可。
【代码实现】
- 创建Router类 实现单例。
- 声明一个Map集合 Map<String,<? extends Activity>>。
- 添加注册方法 给Map中添加需要注册的数据。
- 添加跳转方法 通过Key获取对应Value 实现跳转。
- 在Application中调用注册方法 把需要跳转的类传进去。
【简单优化】
原因:以上的实现方法有弊端,就是在Application注册的的时候,需要把每一个类都添加到Map集 合中,这样就太繁琐了,很累。
优化:
- 创建一个接口添加一个注册方法 map为参数 例如:IRouterLoad void loadInfo()
- 在组件中创建一文件夹 例如:routers 在此文件夹下创建类并实现IRouterLoad接口 在loadInfo方法中给Map集合添加需要注册的类 【注意:在组件java下创建】
- 在单例类中实现 init方法 用于获取apk中包名下routers下所有的类 并创建 调用注册方法。【通过Application拿到包管理器(PackageManager)获取Apk地址 sourceDir】【使用DexFile类加载所有class】【循环遍历所有class 通过反射拿到接口实现类】
- 在Application调用Router.init()即可。
【升级优化】
原因:以上操作优化了Application里的注册操作 ,但是还需要在组件接口实现类中给Map一一添 加需要跳转的activity,同时避免我的框架使用者不去创建实现IRouterLoad接口类,所以再 次优化。
优化:由于IRouterLoad接口实现类的代码模板都一样,只不过类名和数据不同,所以可以使用 javac处理注解再交给javac提供的APT注解处理器来生成模板代码,并动态传入参数。 【javac编译java源文件拿到特定的注解的信息,再通过注解处理器来执行代码操作】
- 创建一个注解类【用于在Activity声明】【单独创建java或android library】
- 创建注解处理器【单独创建java library】【只能在java library里继承AbstractProcessor处理器】【注意:需要手动或者使用auto-service库注册声明注解处理器】【手动注册声明:创建固定文件 main\resources\META-INF\services\javax.annotation.processing.Processor】【在此文件里写入注解处理器包名】
- 在注解处理器中可以捕获到自己定义的注解 拿到数据带入到模板代码里并创建该java类 最后调用输出流输出【声明定义的注解 该注解处理器只处理自己的注解】【生成java代码两种方式:1、注解处理器提供的JavaFileObject 2、Java的javapoet库 提供的 TypeSpec、MethodSpec、JavaFile】
- 这次优化就到这了 在编译的时候我已经把我的路由表注册好了,省去了手动在IRouterLoad 实现类里一一注册。
【终极优化】
原因:因为Router.init()中循环遍历项目里所有类太耗时。
优化:结合字节码插桩技术和Gradled的Transform、自定义插件来解决。或者 模仿阿里路由 判断项目的新老版本号 使用SharedPreferences来缓存路由表 也就是Map集合。
简单的一个路由框架就实现了。
总结:
对于项目太大业务太多不好管理 开发过程中编译也是很头疼 组件化开发对我们来说实在是太友好了,组件化分为App壳层、业务组件层、功能组件层、公共基础库层。严格来说业务组件之间是不允许互相依赖的,但是也避免不了有个别需求:由A组件跳到B组件或子跳到主的功能 所以需要一个路由来完成子与主 子与子之间的相互跳转,因为组件之间拿不到Activity和子Module拿不到主Module的Activity,所以需要在基础公共层定义一个路由表以key value的映射集合形式存放在堆内存里,各个业务组件只需要给路由表中注册自己的Activity,别的组件拿到就可以完成跳转。为了避免频繁或忘记和错误的注册,在javac编译代码的源文件利用Apt(注解处理器),处理自己特定的注解(给每个Activity添加注解 并传入路由表中的K值),拿到注解数据传入到模板代码中自动生成java类文件,由class类加载遍历出所有的类,通过反射拿到自动生成的java类,最后执行往路由表中添加Activity的操作。