前言
創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于做網(wǎng)站、成都做網(wǎng)站、共和網(wǎng)絡(luò)推廣、微信小程序、共和網(wǎng)絡(luò)營銷、共和企業(yè)策劃、共和品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供共和建站搭建服務(wù),24小時(shí)服務(wù)熱線:18980820575,官方網(wǎng)址:vcdvsql.cn
什么是Apt
APT從原理上講是一個(gè)編譯期的注解處理工具(Annotation Processing Tool)。一些主流的三方庫(ButterKnife,Glide)都用到了這個(gè)技術(shù)來生成代碼。
Apt有什么好處
Gradle腳本中的apt和annotationProcessor
這兩個(gè)從廣義上說都是編譯期的注解處理工具。只不過android-apt(其實(shí)是一個(gè)gradle插件,apt是插件命令)是早期的github的一個(gè)開源項(xiàng)目,annotationProcessor是gradle build tools 2.2之后自帶的編譯期注解工具(官方支持的,可替代開源的gradle插件android-apt)。android-apt的作者已經(jīng)發(fā)表聲明表示Android Studio插件已經(jīng)支持annotationProcessor,并且會(huì)警告和阻止使用android-apt。總的來說,看你的gradle build tools的版本,低版本用android-apt(需要引入插件),高版本用annotationProcessor(無需引入插件)
代碼設(shè)計(jì)
需求分析
這里將route模塊分成三部分(一個(gè)android library,兩個(gè)java library)
1、router-annotation(java library)
這里java工程里面只放注解的聲明類。這里只實(shí)現(xiàn)了兩個(gè)注解RouterActivity、RouterField。
2、router-compiler (java library)
這個(gè)工程是編譯期依賴的工程,作用是編譯期掃描代碼,根據(jù)RouterActivity、RouterField這兩個(gè)注解的使用,生成相關(guān)代碼。這里需要講下如何掃描代碼并且生成代碼的。這部分功能的實(shí)現(xiàn)主要依賴兩個(gè)庫:Google的auto-service(掃描代碼),Squareup的javapoet(生成代碼)
3、router (android library)
主要邏輯代碼。在這個(gè)模塊中會(huì)定義一些功能類和接口。router-compiler模塊可以根據(jù)這些接口和功能類generate邏輯代碼。需要注意的是router-compiler是不需要依賴router的,router-compiler是根據(jù)包名+類名的方式獲取類的。
代碼實(shí)現(xiàn)
router-annotation
RouterActivity是一個(gè)注解,用此注解修飾的Activity根據(jù)指定的路由地址,會(huì)自動(dòng)添加到路由表中,當(dāng)系統(tǒng)掛載了路由表之后,就可根據(jù)指定的路由地址來訪問特定的Activity了。代碼如下:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface RouterActivity { String[] value(); }
這里Activity可用多個(gè)路由地址修改。
RouterField是一個(gè)用于表示Activity跳轉(zhuǎn)時(shí)參數(shù)傳遞的注解,用這個(gè)注解修飾的成員變量,表示為接收Intent參數(shù)的變量。
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface RouterField { String[] value(); }
router-compiler
這個(gè)模塊只包含一個(gè)類RouterProcessor,這個(gè)類的大致結(jié)構(gòu)如下:
//此處用AutoService注解,就可實(shí)現(xiàn)編譯期自動(dòng)掃描代碼 @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中讀取一些配置項(xiàng) } @Override public SourceVersion getSupportedSourceVersion() { //表示支持的Jdk版本 return SourceVersion.RELEASE_7; } }
下面分別講解一下函數(shù)的實(shí)現(xiàn):
1、init函數(shù)
我們的項(xiàng)目大多都是多module的形式,這時(shí)候我們就需要為每個(gè)module創(chuàng)建一個(gè)Activity路由注冊(cè)表,然后在Application初始化的時(shí)候?qū)⑺械穆酚勺?cè)表掛載上,達(dá)到Activity路由跳轉(zhuǎn)的目的。這里我們?cè)趇nit函數(shù)中,配置每個(gè)模塊路由表的前綴名稱。
@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ù)
這個(gè)函數(shù)的大致流程如下:找到所有被RouterActivity修飾的Activity;實(shí)現(xiàn)router模塊中的RouterInitializer接口,將每個(gè)Activity的路由地址加入路由表中;同時(shí)為每個(gè)Activity創(chuàng)建一個(gè)XXXActivityHelper(用于更友好的Activity調(diào)整),并將每個(gè)XXXAcitivyHelper放入RouterHelper中,提供get方法獲取。process函數(shù)的具體實(shí)現(xiàn),可詳見項(xiàng)目源碼(都是一些代碼生成的語句,沒有多少邏輯)。
router
代碼使用
初始化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目錄生成的代碼如下:
詳細(xì)代碼可查看:Github項(xiàng)目。
現(xiàn)階段代碼還不完善,后期會(huì)添加更多功能。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
網(wǎng)站欄目:AndroidApt之ActivityRoute的示例
網(wǎng)頁URL:http://vcdvsql.cn/article20/jhgejo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、網(wǎng)站導(dǎo)航、微信公眾號(hào)、外貿(mào)建站、網(wǎng)站內(nèi)鏈、App開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)