09.使用註解搭建路由[綜合案例]php
1.Annotation庫的簡單介紹 2.@Nullable和@NonNull 3.資源類型註釋 4.類型定義註釋 5.線程註釋 6.RGB顏色紙註釋 7.值範圍註釋 8.權限註釋 9.重寫函數註釋 10.返回值註釋 11.@Keep註釋 12.@SuppressWarnings註解 13.其餘
03.註解詳細介紹android
04.APT技術詳解git
06.自定義annotation註解github
07.註解之兼容kotlinsegmentfault
什麼是apt
編譯時註解。
大概原理
annotationProcessor和apt區別
什麼是jack編譯方式?
Jack工具的主要優點
項目目錄結構如圖:
使用apt實現點擊事件【編譯期註解生成代碼】
使用apt實現setContentView功能【運行期註解案例】
使用apt實現路由【綜合型案例】
以下所示
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化OnceClick,並設置點擊事件間隔是2秒 OnceInit.once(this,2000); } @OnceClick(R.id.tv_1) public void Click1(){ Log.d("tag--------------------","tv_1"); }
以下所示,在app/build/generated/source/apt/debug/MainActivity$$_Once_Proxy目錄下
// 編譯生成的代碼,不要修改 // 更多內容:https://github.com/yangchong211 package com.ycbjie.ycapt; import android.view.View; import com.ycbjie.api.Finder; import com.ycbjie.api.AbstractInjector; public class MainActivity$$_Once_Proxy<T extends MainActivity> implements AbstractInjector<T> { public long intervalTime; @Override public void setIntervalTime(long time) { intervalTime = time; } @Override public void inject(final Finder finder, final T target, Object source) { View view; view = finder.findViewById(source, 2131165325); if(view != null){ view.setOnClickListener(new View.OnClickListener() { long time = 0L; @Override public void onClick(View v) { long temp = System.currentTimeMillis(); if (temp - time >= intervalTime) { time = temp; target.Click1(); } }}); } view = finder.findViewById(source, 2131165326); if(view != null){ view.setOnClickListener(new View.OnClickListener() { long time = 0L; @Override public void onClick(View v) { long temp = System.currentTimeMillis(); if (temp - time >= intervalTime) { time = temp; target.Click2(v); } }}); } } }
首先先定義自定義註解
//@Retention用來修飾這是一個什麼類型的註解。這裏表示該註解是一個運行時註解。 @Retention(RetentionPolicy.RUNTIME) //@Target用來表示這個註解可使用在哪些地方。好比:類、方法、屬性、接口等等。 //這裏ElementType.TYPE 表示這個註解能夠用來修飾:Class, interface or enum declaration。 //當你用ContentView修飾一個方法時,編譯器會提示錯誤。 @Target({ElementType.TYPE}) //這裏的interface並非說ContentView是一個接口。 //就像申明類用關鍵字class。申明枚舉用enum。申明註解用的就是@interface。 public @interface ContentView { //返回值表示這個註解裏能夠存放什麼類型值。 int value(); }
而後須要在activity中作註解解析
@SuppressLint("Registered") public class ContentActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //註解解析 //遍歷全部的子類 for (Class c = this.getClass(); c != Context.class; c = c.getSuperclass()) { assert c != null; //找到修飾了註解ContentView的類 ContentView annotation = (ContentView) c.getAnnotation(ContentView.class); if (annotation != null) { try { //獲取ContentView的屬性值 int value = annotation.value(); //調用setContentView方法設置view this.setContentView(value); } catch (RuntimeException e) { e.printStackTrace(); } return; } } } }
關於如何使用,注意你寫的Activity須要實現ContentActivity,才能讓註解生效
@ContentView(R.layout.activity_four) public class FourActivity extends ContentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); findViewById(R.id.tv_1).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(FourActivity.this,"運行期註解",Toast.LENGTH_SHORT).show(); } }); } }
[9.6 路由框架設計注意要點]()
9.9 路由開源庫的使用
不帶參數直接跳轉
@Router(path = Path.six) public class SixActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_six); } } ARouter.getsInstance().build(Path.six) .navigation(MainActivity.this, new NavigationCallback() { @Override public void onFound(Postcard postcard) { Log.e("NavigationCallback","找到跳轉頁面"); } @Override public void onLost(Postcard postcard) { Log.e("NavigationCallback","未找到"); } @Override public void onArrival(Postcard postcard) { Log.e("NavigationCallback","成功跳轉"); } });
帶參數跳轉
@Router(path = Path.five) public class FiveActivity extends AppCompatActivity { @Extra String title; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_five); //添加這行代碼,實際上就是自動生成了下面獲取參數值的代碼 ARouter.getsInstance().inject(this); //若是不添加插入註解,則能夠直接用下面的代碼。 //Intent intent = getIntent(); //String title = intent.getStringExtra("title"); Toast.makeText(this, "title=" + title, Toast.LENGTH_SHORT).show(); } } Bundle bundle = new Bundle(); bundle.putString("title","標題-------------"); ARouter.getsInstance() .build(Path.five) .withBundle(bundle) .navigation();
路由註解生成的代碼位置