日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

【Android 组件化】路由组件 ( 构造路由表中的路由信息 )

發(fā)布時間:2025/6/17 Android 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Android 组件化】路由组件 ( 构造路由表中的路由信息 ) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 一、封裝路由信息
  • 二、注解處理器 生成路由表信息
    • 1、Activity 中使用 @Route 注解
    • 2、注解處理器中判定注解是否檢測出來
    • 3、獲取被 @Route 標注的 注解節(jié)點
    • 4、判斷被 @Route 標注的 注解節(jié)點的類型
    • 5、路由信息分組
  • 三、完整的 注解處理器 代碼
  • 四、博客資源

組件化系列博客 :

  • 【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 組件化】路由組件 ( 注解處理器參數(shù)選項設(shè)置 ) 博客中在注解處理器中 , 獲取了在 build.gradle 中設(shè)置的參數(shù) ;

本篇博客中講解 " 注解處理器 " 后續(xù)開發(fā) , 生成路由表中的 路由信息 ;





一、封裝路由信息



在 " 編譯時注解 " 依賴庫 Module 中 , 定義 封裝 路由信息 的 JavaBean 類 , 其中需要封裝以下數(shù)據(jù) ;

① 被 " kim.hsl.router_annotation.Route " 注解的 路由類型 , Activity 界面組件 / Service 服務(wù)組件 ;

② 被 " kim.hsl.router_annotation.Route " 注解的 " javax.lang.model.element.Element " 類型 注解節(jié)點 ;

③ 被 " kim.hsl.router_annotation.Route " 注解的 Activity 界面組件 / Service 服務(wù)組件的 組件類對象 ;

路由地址 , 字符串類型 ,

路由分組 , 字符串類型 , 將路由信息根據(jù)路由分組拆分開進行放置 ,


代碼示例 :

package kim.hsl.router_annotation.model;import javax.lang.model.element.Element; import kim.hsl.router_annotation.Route;/*** 存儲路由節(jié)點信息的 Bean*/ public class RouteBean {/*** 注解類的類型* Activity 界面 / Service 服務(wù)*/public enum Type {ACTIVITY,SERVICE}private Type type;/*** 被注解的節(jié)點*/private Element element;/*** 被注解類*/private Class<?> clazz;/*** 路由地址*/private String routeAddress;/*** 路由組*/private String routeGroup;public RouteBean(Type type, Element element, Route route) {this.type = type;this.element = element;this.clazz = null;this.routeAddress = route.path();this.routeGroup = route.group();}public RouteBean(Type type, Element element, Class<?> clazz, String routeAddress, String routeGroup) {this.type = type;this.element = element;this.clazz = clazz;this.routeAddress = routeAddress;this.routeGroup = routeGroup;}public Type getType() {return type;}public void setType(Type type) {this.type = type;}public Element getElement() {return element;}public void setElement(Element element) {this.element = element;}public Class<?> getClazz() {return clazz;}public void setClazz(Class<?> clazz) {this.clazz = clazz;}public String getRouteAddress() {return routeAddress;}public void setRouteAddress(String routeAddress) {this.routeAddress = routeAddress;}public String getRouteGroup() {return routeGroup;}public void setRouteGroup(String routeGroup) {this.routeGroup = routeGroup;} }



二、注解處理器 生成路由表信息





1、Activity 中使用 @Route 注解


下面開始開發(fā) AbstractProcessor 注解處理器中的 process 方法 , 在該方法中生成 Java 代碼 ;

在 MainActivity 中使用了 @Route(path = “/app/MainActivity”) 標注了 MainActivity 類 ;

@Route(path = "/app/MainActivity") public class MainActivity extends Activity { }

2、注解處理器中判定注解是否檢測出來


在 注解處理器 中的 process 方法中 , 首先判定解析到了 注解節(jié)點 , 如果沒有解析到注解節(jié)點 , 就立刻退出 , 參考之前出現(xiàn)的問題 【錯誤記錄】Android 編譯時技術(shù)報錯 ( 注解處理器 process 方法多次調(diào)用問題 ) ;

if (set == null || set.isEmpty()){// 如果沒有檢測到注解 , 直接退出return false; }

3、獲取被 @Route 標注的 注解節(jié)點


獲取被 Route 注解標注的類節(jié)點 , 調(diào)用 RoundEnvironment 參數(shù)的 getElementsAnnotatedWith 方法 , 傳入要獲取的注解類對象 ;

// 獲取被 @Route 注解的節(jié)點 // 這些 注解節(jié)點 都是類節(jié)點 , TypeElement 類型的 Set<? extends Element> routeElements = roundEnvironment.getElementsAnnotatedWith(Route.class);

4、判斷被 @Route 標注的 注解節(jié)點的類型


判斷被 @Route 標注的 注解節(jié)點的類型 : 是否是 Activity 子類類型 ;

獲取 android.app.Activity 類型的 的 TypeElement 注解節(jié)點 ;

// 獲取 android.app.Activity 類型的注解節(jié)點 TypeElement activityElement = mElementUtils.getTypeElement("android.app.Activity");

判定獲取的 Set<? extends Element> routeElements 節(jié)點是否是 " android.app.Activity " 子類節(jié)點 , 如果是則創(chuàng)建路由信息對象 ;

mTypeUtils.isSubtype(element.asType(), activityElement.asType())

創(chuàng)建路由信息對象 完整代碼示例 :

private void generateRouteClass(Set<? extends Element> routeElements) {// 獲取 android.app.Activity 類型的注解節(jié)點TypeElement activityElement = mElementUtils.getTypeElement("android.app.Activity");// 處理 @Route(path = "app/MainActivity") 節(jié)點for (Element element : routeElements) {// 獲取 Route 注解Route route = element.getAnnotation(Route.class);// 路由表中的單個路由對象RouteBean routeBean = null;// 打印類節(jié)點全類名mMessager.printMessage(Diagnostic.Kind.NOTE,"打印類節(jié)點 typeElement : " + activityElement.getQualifiedName());// 判斷 typeMirror 注解節(jié)點是否是 Activity 類型if (mTypeUtils.isSubtype(element.asType(), activityElement.asType())) {// 該節(jié)點是 android.app.Activity 類型的routeBean = new RouteBean(RouteBean.Type.ACTIVITY, // 路由對象類型element, // 路由節(jié)點null, // 類對象route.path(), // 路由地址route.group()); // 路由組// 檢查路由地址checkRouteAddress(routeBean);// 打印路由信息mMessager.printMessage(Diagnostic.Kind.NOTE,"打印路由信息 : " + routeBean.toString());}else{// 該節(jié)點不是 android.app.Activity 類型的throw new RuntimeException("@Route 注解節(jié)點類型錯誤");}}}

5、路由信息分組


每個路由信息都有一個分組 , 在定義 Route 注解時 , 分組為 “” 空字符串 ;

@Target({ElementType.TYPE}) @Retention(RetentionPolicy.CLASS) public @interface Route {/*** 路由路徑, 標識一個路由節(jié)點* 該字段沒有默認值, 必須設(shè)置* @return*/String path();/*** 路由分組, 默認為空, 選擇性設(shè)置* 路由節(jié)點可以按照分組進行加載* @return*/String group() default ""; }

根據(jù)設(shè)置的路由路徑 , @Route(path = “/app/MainActivity”) 中的 “/app/MainActivity” , 將其中的 app 作為路由分組 ;

截取路由地址 “/app/MainActivity” 中前兩個斜線之間字符串作為路由分組 ;

/*** 驗證路由地址* @Route(path = "/app/MainActivity")* @param routeBean*/private void checkRouteAddress(RouteBean routeBean){// 獲取路由地址String routeAddress = routeBean.getRouteAddress();// 獲取路由分組String routeGroup = routeBean.getRouteGroup();// 驗證路由地址是否以 "/" 開頭if (!routeAddress.startsWith("/")) {throw new RuntimeException("路由地址 " + routeAddress + " 格式錯誤");}// 如果路由地址的分組為空 ,// 則截取第 0 和 第 1 個 "/" 之間的字符串作為分組名稱if (routeGroup == null || "".equals(routeGroup)){String group = routeAddress.substring(routeAddress.indexOf("/", 0) + 1,routeAddress.indexOf("/", 1));if (group == null || "".equals(group)){throw new RuntimeException("路由地址 " + routeAddress + " 獲取分組錯誤");}// 打印組名mMessager.printMessage(Diagnostic.Kind.NOTE,"打印路由地址 " + routeAddress + " 的組名為 " + group);// 正式設(shè)置路由地址分組routeBean.setRouteGroup(group);}}



三、完整的 注解處理器 代碼



完整的 注解處理器 代碼 :

package kim.hsl.router_compiler;import com.google.auto.service.AutoService;import java.util.Map; import java.util.Set;import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.Filer; import javax.annotation.processing.Messager; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.Processor; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; import javax.annotation.processing.SupportedOptions; import javax.annotation.processing.SupportedSourceVersion; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; import javax.tools.Diagnostic;import kim.hsl.router_annotation.Route; import kim.hsl.router_annotation.model.RouteBean;// 注解處理器接收的參數(shù) @SupportedOptions("moduleName") // 自動注冊注解處理器 @AutoService(Processor.class) // 支持的注解類型 @SupportedAnnotationTypes({"kim.hsl.router_annotation.Route"}) // 支持的 Java 版本 @SupportedSourceVersion(SourceVersion.RELEASE_8) public class RouterProcessor extends AbstractProcessor {/*** 注解處理器中使用 Messager 對象打印日志*/private Messager mMessager;/*** 用于寫出生成的 Java 代碼*/private Filer mFiler;/*** 注解節(jié)點工具*/private Elements mElementUtils;/*** 類工具*/private Types mTypeUtils;/*** 獲取的 moduleName 參數(shù)*/private String mModuleName;/*** 該函數(shù)在初始化時調(diào)用 , 相當(dāng)于構(gòu)造函數(shù)* @param processingEnvironment*/@Overridepublic synchronized void init(ProcessingEnvironment processingEnvironment) {super.init(processingEnvironment);// 獲取打印日志接口this.mMessager = processingEnvironment.getMessager();// 測試日志打印mMessager.printMessage(Diagnostic.Kind.NOTE, "Messager Print Log");this.mFiler = processingEnvironment.getFiler();this.mElementUtils = processingEnvironment.getElementUtils();this.mTypeUtils = processingEnvironment.getTypeUtils();// 獲取 moduleName 參數(shù)// 先獲取 注解處理器 選項Map<String, String> options = processingEnvironment.getOptions();if (options != null){mModuleName = options.get("moduleName");mMessager.printMessage(Diagnostic.Kind.NOTE, "打印 moduleName 參數(shù) : " + mModuleName);}}/*** 該函數(shù)在注解處理器注冊時自動執(zhí)行, 是處理注解的核心函數(shù)** Set<? extends TypeElement> set 參數(shù) : 該集合表示使用了相關(guān)注解的節(jié)點的集合** @param set* @param roundEnvironment* @return*/@Overridepublic boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {if (set == null || set.isEmpty()){// 如果沒有檢測到注解 , 直接退出return false;}// 獲取被 @Route 注解的節(jié)點// 這些 注解節(jié)點 都是類節(jié)點 , TypeElement 類型的Set<? extends Element> routeElements = roundEnvironment.getElementsAnnotatedWith(Route.class);generateRouteClass(routeElements);return false;}private void generateRouteClass(Set<? extends Element> routeElements) {// 獲取 android.app.Activity 類型的注解節(jié)點TypeElement activityElement = mElementUtils.getTypeElement("android.app.Activity");// 處理 @Route(path = "app/MainActivity") 節(jié)點for (Element element : routeElements) {// 獲取 Route 注解Route route = element.getAnnotation(Route.class);// 路由表中的單個路由對象RouteBean routeBean = null;// 打印類節(jié)點全類名mMessager.printMessage(Diagnostic.Kind.NOTE,"打印類節(jié)點 typeElement : " + activityElement.getQualifiedName());// 判斷 typeMirror 注解節(jié)點是否是 Activity 類型if (mTypeUtils.isSubtype(element.asType(), activityElement.asType())) {// 該節(jié)點是 android.app.Activity 類型的routeBean = new RouteBean(RouteBean.Type.ACTIVITY, // 路由對象類型element, // 路由節(jié)點null, // 類對象route.path(), // 路由地址route.group()); // 路由組// 檢查路由地址checkRouteAddress(routeBean);// 打印路由信息mMessager.printMessage(Diagnostic.Kind.NOTE,"打印路由信息 : " + routeBean.toString());}else{// 該節(jié)點不是 android.app.Activity 類型的throw new RuntimeException("@Route 注解節(jié)點類型錯誤");}}}/*** 驗證路由地址* @Route(path = "/app/MainActivity")* @param routeBean*/private void checkRouteAddress(RouteBean routeBean){// 獲取路由地址String routeAddress = routeBean.getRouteAddress();// 獲取路由分組String routeGroup = routeBean.getRouteGroup();// 驗證路由地址是否以 "/" 開頭if (!routeAddress.startsWith("/")) {throw new RuntimeException("路由地址 " + routeAddress + " 格式錯誤");}// 如果路由地址的分組為空 ,// 則截取第 0 和 第 1 個 "/" 之間的字符串作為分組名稱if (routeGroup == null || "".equals(routeGroup)){String group = routeAddress.substring(routeAddress.indexOf("/", 0) + 1,routeAddress.indexOf("/", 1));if (group == null || "".equals(group)){throw new RuntimeException("路由地址 " + routeAddress + " 獲取分組錯誤");}// 打印組名mMessager.printMessage(Diagnostic.Kind.NOTE,"打印路由地址 " + routeAddress + " 的組名為 " + group);// 正式設(shè)置路由地址分組routeBean.setRouteGroup(group);}} }

執(zhí)行結(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'}





四、博客資源



博客源碼 :

  • GitHub : https://github.com/han1202012/Component
  • CSDN 下載 :


總結(jié)

以上是生活随笔為你收集整理的【Android 组件化】路由组件 ( 构造路由表中的路由信息 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。