【Android 组件化】路由组件 ( 使用 JavaPoet 生成路由表类 )
文章目錄
- 一、要生成的路由表類
- 二、生成 路由表 過程
- 1、獲取其它類節(jié)點
- 2、生成參數(shù)
- 3、路由表結(jié)構(gòu)
- 4、函數(shù)創(chuàng)建
- 5、Java 類創(chuàng)建
- 6、寫出 Java 源碼到文件中
- 三、完整注解處理器及運行結(jié)果
- 1、完整注解處理器代碼
- 2、執(zhí)行結(jié)果
- 四、博客資源
組件化系列博客 :
- 【Android 組件化】從模塊化到組件化
- 【Android 組件化】使用 Gradle 實現(xiàn)組件化 ( Gradle 變量定義與使用 )
- 【Android 組件化】使用 Gradle 實現(xiàn)組件化 ( 組件模式與集成模式切換 )
- 【Android 組件化】使用 Gradle 實現(xiàn)組件化 ( 組件 / 集成模式下的 Library Module 開發(fā) )
- 【Android 組件化】路由組件 ( 路由組件結(jié)構(gòu) )
- 【Android 組件化】路由組件 ( 注解處理器獲取被注解的節(jié)點 )
- 【Android 組件化】路由組件 ( 注解處理器中使用 JavaPoet 生成代碼 )
- 【Android 組件化】路由組件 ( 注解處理器參數(shù)選項設(shè)置 )
- 【Android 組件化】路由組件 ( 構(gòu)造路由表中的路由信息 )
在 【Android 組件化】路由組件 ( 構(gòu)造路由表中的路由信息 ) 博客中解析了注解的節(jié)點及注解屬性 , 將路由信息封裝在了 RouteBean 中 ;
本篇博客中開始分組管理這些 RouteBean ;
一、要生成的路由表類
將上一篇博客 【Android 組件化】路由組件 ( 構(gòu)造路由表中的路由信息 ) 中封裝的 路由信息 對象 , 放在 HashMap 中管理 ,
鍵 ( Key ) : 路由分組 名稱 ;
值 ( Value ) : 路由信息 RouteBean 集合 ;
因此在上一篇博客中 , 必須為每個 路由信息 " RouteBean " 設(shè)置一個分組 ;
/*** 管理路由信息* 鍵 ( Key ) : 路由分組名稱* 值 ( Value ) : 路由信息集合*/ private HashMap<String, ArrayList<RouteBean>> mGroupMap = new HashMap<>();目標(biāo)是生成如下 Java 類 :
package kim.hsl.router;import java.lang.Override; import java.lang.String; import java.util.Map; import kim.hsl.component.MainActivity; import kim.hsl.route_core.template.IRouteGroup; import kim.hsl.router_annotation.model.RouteBean;public class Router_Group_app implements IRouteGroup {@Overridepublic void loadInto(Map<String, RouteBean> atlas) {atlas.put("app", new RouteBean(RouteBean.Type.ACTIVITY, MainActivity.class, "/app/MainActivity", "app"));} }二、生成 路由表 過程
1、獲取其它類節(jié)點
獲取 需要實現(xiàn)的接口 , 該接口定義在 router-core 模塊中 , 該模塊是 Android Library Module 類型的 , 主應(yīng)用使用 api 依賴該模塊即可 ;
// 獲取要生成的類 需要實現(xiàn)的接口節(jié)點 TypeElement iRouteGroup = mElementUtils.getTypeElement("kim.hsl.route_core.template.IRouteGroup"); // 打印類節(jié)點全類名 mMessager.printMessage(Diagnostic.Kind.NOTE,"打印類節(jié)點 iRouteGroup : " + iRouteGroup.getQualifiedName());2、生成參數(shù)
生成函數(shù)參數(shù) Map<String, RouteBean> atlas ,
ParameterizedTypeName 是參數(shù)類型名稱 , Map 類型的話 , 在 Map 類型后面連續(xù)傳入兩個類型名稱 , 作為鍵值對的參數(shù)名稱 ;
ParameterSpec 是完整參數(shù) , 調(diào)用 ParameterSpec.builder 方法創(chuàng)建 , 傳入 參數(shù)類名名稱 和 參數(shù)變量名 ;
// 生成參數(shù)類型 Map<String, RouteBean> atlas ParameterizedTypeName atlasType = ParameterizedTypeName.get(ClassName.get(Map.class),ClassName.get(String.class),ClassName.get(RouteBean.class) ); // 生成參數(shù) Map<String, RouteBean> atlas ParameterSpec atlasValue = ParameterSpec.builder(atlasType, "atlas").build();3、路由表結(jié)構(gòu)
遍歷成員變量 HashMap<String, ArrayList<RouteBean>> mGroupMap , 其中每個組名都生成一個路由表 ;
// 遍歷 HashMap<String, ArrayList<RouteBean>> mGroupMap = new HashMap<>() 路由分組 // 為每個 路由分組 創(chuàng)建一個類 for (Map.Entry<String, ArrayList<RouteBean>> entry : mGroupMap.entrySet()){ }4、函數(shù)創(chuàng)建
創(chuàng)建函數(shù) , 以及生成函數(shù)體代碼 ;
創(chuàng)建的函數(shù)內(nèi)容 :
@Overridepublic void loadInto(Map<String, RouteBean> atlas) {atlas.put("app", new RouteBean(RouteBean.Type.ACTIVITY, MainActivity.class, "/app/MainActivity", "app"));}先創(chuàng)建函數(shù)構(gòu)建器 MethodSpec.Builder ,
調(diào)用 MethodSpec.methodBuilder 方法創(chuàng)建該構(gòu)建器 , 參數(shù)中設(shè)置函數(shù)名 ,
調(diào)用 addModifiers 設(shè)置函數(shù)的屬性 , 可見性 public , 是否靜態(tài) static 等 , 可以設(shè)置多個 ;
調(diào)用 addAnnotation 方法設(shè)置注解類型 ,
調(diào)用 addParameter 方法設(shè)置參數(shù)類名 ;
// 創(chuàng)建函數(shù) loadInto MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder("loadInto").addModifiers(Modifier.PUBLIC).addAnnotation(Override.class).addParameter(atlasValue);函數(shù)體中的代碼 , 需要遍歷 mGroupMap 中的值 , 進(jìn)行生成 ; 每個路由信息 RouteBean 都要生成一條路由數(shù)據(jù) , 如下 :
atlas.put("app", new RouteBean(RouteBean.Type.ACTIVITY, MainActivity.class, "/app/MainActivity", "app"));拼接復(fù)雜函數(shù)函數(shù)聲明 , 參考如下代碼及注釋 ,
調(diào)用 methodBuilder.addStatement 方法 , 創(chuàng)建函數(shù)體聲明代碼 , 第一個參數(shù)是模板 ,
- $S 表示字符串 , 替換時會加上雙引號
- $T 表示類
- $L 表示字面量 , 原封不動的字符串替換
函數(shù)創(chuàng)建部分代碼 :
// 創(chuàng)建函數(shù) loadInto MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder("loadInto").addModifiers(Modifier.PUBLIC).addAnnotation(Override.class).addParameter(atlasValue);// 函數(shù)體中的代碼生成 // 獲取 ArrayList<RouteBean> 數(shù)據(jù) ArrayList<RouteBean> groupRoutes = entry.getValue();// 組名 String groupName = "";// 生成函數(shù)體代碼 for (RouteBean routeBean : groupRoutes){// 獲取組名groupName = routeBean.getRouteGroup();// $S 表示字符串// $T 表示類// $L 表示字面量 , 原封不動的字符串替換methodBuilder.addStatement("atlas.put($S, new $T($T.$L, $T.class, $S, $S))",// $S 字符串 : "main"routeBean.getRouteGroup(),// $T 類名 : RouteBeanClassName.get(RouteBean.class),// $T 類名 : TypeClassName.get(RouteBean.Type.class),// $L 字面量 : ACTIVITYrouteBean.getType(),// $T 類名 : kim.hsl.component.MainActivity 類ClassName.get((TypeElement) routeBean.getElement()),// $S 字符串 : "/app/MainActivity"routeBean.getRouteAddress(),// $S 字符串 : "app"routeBean.getRouteGroup()); }5、Java 類創(chuàng)建
調(diào)用 TypeSpec.classBuilder 方法 , 創(chuàng)建 Java 類 , 傳入類名作為參數(shù) ,
addSuperinterface 方法用于設(shè)置實現(xiàn)的接口 ,
addModifiers 方法設(shè)置類的其它參數(shù) , 如可見性 , 靜態(tài) ;
addMethod 方法設(shè)置類的方法 ;
最后調(diào)用 build 方法生成類 ;
// 創(chuàng)建類 // 構(gòu)造類名 Router_Group_main String groupClassName = "Router_Group_" + groupName; // 創(chuàng)建類 TypeSpec typeSpec = TypeSpec.classBuilder(groupClassName).addSuperinterface(ClassName.get(iRouteGroup)).addModifiers(PUBLIC).addMethod(methodBuilder.build()).build(); // 生成 Java 源碼文件 JavaFile javaFile = JavaFile.builder("kim.hsl.router", typeSpec).build();6、寫出 Java 源碼到文件中
將上述生成的 Java 源碼寫出到文件中 ;
// 將 Java 源文件寫出到相應(yīng)目錄中 try {javaFile.writeTo(mFiler); } catch (IOException e) {e.printStackTrace(); }// 統(tǒng)計路由表信息 mRootMap.put(groupName, groupClassName);三、完整注解處理器及運行結(jié)果
1、完整注解處理器代碼
生成的 Java 源代碼 : 生成的源碼路徑 " D:\002_Project\002_Android_Learn\Component\app\build\generated\ap_generated_sources\debug\out\kim\hsl\router\Router_Group_app.java "
package kim.hsl.router;import java.lang.Override; import java.lang.String; import java.util.Map; import kim.hsl.component.MainActivity; import kim.hsl.route_core.template.IRouteGroup; import kim.hsl.router_annotation.model.RouteBean;public class Router_Group_app implements IRouteGroup {@Overridepublic void loadInto(Map<String, RouteBean> atlas) {atlas.put("app", new RouteBean(RouteBean.Type.ACTIVITY, MainActivity.class, "/app/MainActivity", "app"));} }2、執(zhí)行結(jié)果
編譯過程打印結(jié)果 :
注: Messager Print Log 注: 打印 moduleName 參數(shù) : app 注: 打印類節(jié)點 typeElement : android.app.Activity 注: 打印路由地址 /app/MainActivity 的組名為 app 注: 打印路由信息 : RouteBean{type=ACTIVITY, element=kim.hsl.component.MainActivity, clazz=null, routeAddress='/app/MainActivity', routeGroup='app'} 注: 打印類節(jié)點 iRouteGroup : kim.hsl.route_core.template.IRouteGroup四、博客資源
博客源碼 :
- GitHub : https://github.com/han1202012/Component
- CSDN 下載 :
總結(jié)
以上是生活随笔為你收集整理的【Android 组件化】路由组件 ( 使用 JavaPoet 生成路由表类 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【错误记录】Android Studio
- 下一篇: 【Android 组件化】路由组件 (