国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android Apt之Activity Route的示例

2019-10-22 18:15:59
字體:
供稿:網(wǎng)友

前言

什么是Apt

APT從原理上講是一個編譯期的注解處理工具(Annotation Processing Tool)。一些主流的三方庫(ButterKnife,Glide)都用到了這個技術(shù)來生成代碼。

Apt有什么好處

  1. 自動生成模板代碼,提高了開發(fā)效率
  2. 編譯期對注解的處理,相對于運行期對注解的處理,性能上要好的多。

Gradle腳本中的apt和annotationProcessor

這兩個從廣義上說都是編譯期的注解處理工具。只不過android-apt(其實是一個gradle插件,apt是插件命令)是早期的github的一個開源項目,annotationProcessor是gradle build tools 2.2之后自帶的編譯期注解工具(官方支持的,可替代開源的gradle插件android-apt)。android-apt的作者已經(jīng)發(fā)表聲明表示Android Studio插件已經(jīng)支持annotationProcessor,并且會警告和阻止使用android-apt。總的來說,看你的gradle build tools的版本,低版本用android-apt(需要引入插件),高版本用annotationProcessor(無需引入插件)

代碼設(shè)計

需求分析

這里將route模塊分成三部分(一個android library,兩個java library)
1、router-annotation(java library)

這里java工程里面只放注解的聲明類。這里只實現(xiàn)了兩個注解RouterActivity、RouterField。

2、router-compiler (java library)

這個工程是編譯期依賴的工程,作用是編譯期掃描代碼,根據(jù)RouterActivity、RouterField這兩個注解的使用,生成相關(guān)代碼。這里需要講下如何掃描代碼并且生成代碼的。這部分功能的實現(xiàn)主要依賴兩個庫:Google的auto-service(掃描代碼),Squareup的javapoet(生成代碼)

3、router (android library)

主要邏輯代碼。在這個模塊中會定義一些功能類和接口。router-compiler模塊可以根據(jù)這些接口和功能類generate邏輯代碼。需要注意的是router-compiler是不需要依賴router的,router-compiler是根據(jù)包名+類名的方式獲取類的。

代碼實現(xiàn)

router-annotation

RouterActivity是一個注解,用此注解修飾的Activity根據(jù)指定的路由地址,會自動添加到路由表中,當(dāng)系統(tǒng)掛載了路由表之后,就可根據(jù)指定的路由地址來訪問特定的Activity了。代碼如下:

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface RouterActivity {  String[] value();}

這里Activity可用多個路由地址修改。

RouterField是一個用于表示Activity跳轉(zhuǎn)時參數(shù)傳遞的注解,用這個注解修飾的成員變量,表示為接收Intent參數(shù)的變量。

@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface RouterField {  String[] value();}

router-compiler

這個模塊只包含一個類RouterProcessor,這個類的大致結(jié)構(gòu)如下:

//此處用AutoService注解,就可實現(xiàn)編譯期自動掃描代碼@AutoService(Processor.class)public class RouterProcessor extends AbstractProcessor{  private Elements elementUtils;  private String targetModuleName = "";  @Override  public Set<String> getSupportedAnnotationTypes() {    //支持的注解類型    return Collections.singleton(RouterActivity.class.getCanonicalName());  }  @Override  public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {   //處理代碼掃描結(jié)果的關(guān)鍵函數(shù)   ...    return true;  }  @Override  public synchronized void init(ProcessingEnvironment processingEnvironment) {    super.init(processingEnvironment);    //在掃描代碼之前可從build.gradle中讀取一些配置項  }  @Override  public SourceVersion getSupportedSourceVersion() {    //表示支持的Jdk版本    return SourceVersion.RELEASE_7;  }}

下面分別講解一下函數(shù)的實現(xiàn):

1、init函數(shù)

我們的項目大多都是多module的形式,這時候我們就需要為每個module創(chuàng)建一個Activity路由注冊表,然后在Application初始化的時候?qū)⑺械穆酚勺员頀燧d上,達到Activity路由跳轉(zhuǎn)的目的。這里我們在init函數(shù)中,配置每個模塊路由表的前綴名稱。

 @Override  public synchronized void init(ProcessingEnvironment processingEnvironment) {    super.init(processingEnvironment);    elementUtils = processingEnvironment.getElementUtils();    Map<String, String> map = processingEnvironment.getOptions();    Set<String> keys = map.keySet();    for (String key: keys) {      if ("targetModuleName".equals(key)) {        this.targetModuleName = map.get(key);      }      System.out.println(key + " + " + map.get(key));

并在module的build.gradle文件下配置如下代碼:

apt {  arguments {    targetModuleName 'moduleName'  }}

2、process函數(shù)

這個函數(shù)的大致流程如下:找到所有被RouterActivity修飾的Activity;實現(xiàn)router模塊中的RouterInitializer接口,將每個Activity的路由地址加入路由表中;同時為每個Activity創(chuàng)建一個XXXActivityHelper(用于更友好的Activity調(diào)整),并將每個XXXAcitivyHelper放入RouterHelper中,提供get方法獲取。process函數(shù)的具體實現(xiàn),可詳見項目源碼(都是一些代碼生成的語句,沒有多少邏輯)。

router

  1. RouterInitializer接口,用于每個module注冊表的實現(xiàn)
  2. ActivityHelper,封裝了一些參數(shù)解析邏輯,更方便的Activity跳轉(zhuǎn)
  3. SafeBundle, 對Activity的參數(shù)進行了封裝
  4. Router, 路由核心類,支持url跳轉(zhuǎn),解析url,并實現(xiàn)跳轉(zhuǎn)。
  5. 'RouterCenterActivity', 可被外部瀏覽器喚起的中轉(zhuǎn)Activity(外面根據(jù)url scheme喚醒RouterCenterActivity,RouterCenterActivity分發(fā)路由地址)

代碼使用

初始化Router

public class DemoApp extends Application {  @Override  public void onCreate() {    super.onCreate();    Router.init("demo"); //自定義scheme協(xié)議  }}

Activity跳轉(zhuǎn)

@RouterActivity({"main"})public class MainActivity extends AppCompatActivity {  @Override  protected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);    findViewById(R.id.btn_second).setOnClickListener(new View.OnClickListener() {      @Override      public void onClick(View v) {        RouterHelper.getSecondActivityHelper().start(MainActivity.this);      }    });  }}@RouterActivity({"second"})public class SecondActivity extends AppCompatActivity {  @Override  protected void onCreate(@Nullable Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_second);  }}

build目錄生成的代碼如下:

Android,Apt,Activity,Route

詳細代碼可查看:Github項目

現(xiàn)階段代碼還不完善,后期會添加更多功能。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


注:相關(guān)教程知識閱讀請移步到Android開發(fā)頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 肥东县| 安平县| 泰和县| 伊通| 绍兴县| 葫芦岛市| 邓州市| 互助| 中西区| 怀柔区| 沽源县| 出国| 汉中市| 桦川县| 彰化县| 大余县| 社旗县| 文山县| 沾化县| 柳江县| 成安县| 平江县| 偏关县| 吉林市| 尉犁县| 正宁县| 阿克| 全椒县| 德庆县| 宜良县| 桃江县| 静乐县| 万荣县| 雷山县| 余干县| 渭源县| 禄丰县| 巍山| 邢台县| 哈巴河县| 手机|