91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android Apt之Activity Route的示例

發布時間:2020-10-20 02:17:02 來源:腳本之家 閱讀:160 作者:三十二蟬 欄目:移動開發

前言

什么是Apt

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

Apt有什么好處

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

Gradle腳本中的apt和annotationProcessor

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

代碼設計

需求分析

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

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

2、router-compiler (java library)

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

3、router (android library)

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

代碼實現

router-annotation

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

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

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

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

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

router-compiler

這個模塊只包含一個類RouterProcessor,這個類的大致結構如下:

//此處用AutoService注解,就可實現編譯期自動掃描代碼
@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) {
   //處理代碼掃描結果的關鍵函數
   ...
    return true;
  }

  @Override
  public synchronized void init(ProcessingEnvironment processingEnvironment) {
    super.init(processingEnvironment);
    //在掃描代碼之前可從build.gradle中讀取一些配置項
  }

  @Override
  public SourceVersion getSupportedSourceVersion() {
    //表示支持的Jdk版本
    return SourceVersion.RELEASE_7;
  }
}

下面分別講解一下函數的實現:

1、init函數

我們的項目大多都是多module的形式,這時候我們就需要為每個module創建一個Activity路由注冊表,然后在Application初始化的時候將所有的路由注冊表掛載上,達到Activity路由跳轉的目的。這里我們在init函數中,配置每個模塊路由表的前綴名稱。

 @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函數

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

router

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

代碼使用

初始化Router

public class DemoApp extends Application {

  @Override
  public void onCreate() {
    super.onCreate();
    Router.init("demo"); //自定義scheme協議
  }
}

Activity跳轉

@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項目。

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

蓝山县| 梨树县| 梁河县| 黎川县| 手游| 庆阳市| 肇州县| 娱乐| 华阴市| 莒南县| 门源| 宜宾县| 义乌市| 拉萨市| 镇赉县| 策勒县| 灵璧县| 噶尔县| 普洱| 信阳市| 星座| 密山市| 乾安县| 诏安县| 江永县| 德化县| 三门县| 永嘉县| 卓资县| 循化| 宁武县| 汪清县| 敖汉旗| 阳原县| 都匀市| 浦县| 宜黄县| 巴林右旗| 同德县| 涪陵区| 杭锦后旗|