Android 路由框架
參考文獻:
superxlcr的ARouter學習筆記
碼字農民工的文章
繁華落盡666的文章
本文主要介紹的知識點
- 關於android路由框架解決的問題
- android路由框架的使用(這裡只是介紹ARouter的使用)
- 關於使用ARouter框架的注意事項
- 總結
1.Android路由框架解決的問題
相信大家在工作中都會遇到這樣的問題,通過其他App或者通過網頁跳轉到指定的自己的App或者跳轉到指定的頁面中去,一般都是在推送中或者通過Banner點選之後的操作,一般的操作都是像下面這樣的
- 設定相應的intent-filter
<intent-filter>
<action android:name="com.hejin.arouter.Main2Activity"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
- 通過Intent隱式跳轉到相應的Activity
Intent intent = new Intent();
intent.setAction("com.hejin.arouter.Main2Activity");
startActivity(intent);
其實這裡我要說明一下,如果你是正規的開發公司我覺得一般都不會這麼去寫,其實這個跳轉完全能實現,但是一般正規的公司都會定一些協議和埠號,也就是說會新增scheme來指定一些資料的協議部分和path進行匹配,但是隨著時間的推移和團隊的擴大,會慢慢的暴露出很多問題:
- 集中式的URL管理:談到集中式的管理,總是比較蛋疼,多人協同開發的時候,大家都去AndroidManifest.xml中定義各種IntentFilter,使用隱式Intent,最終發現AndroidManifest.xml中充斥著各種Schame,各種Path,需要經常解決Path重疊覆蓋、過多的Activity被匯出,引發安全風險等問題
- 可配置性較差:Manifest限制於xml格式,書寫麻煩,配置複雜,可以自定義的東西也較少
- 跨模組無法顯式依賴:在App小有規模的時候,我們會對App做水平拆分,按照業務拆分成多個子模組,之間完全解耦,通過打包流程控制App功能,這樣方便應對大團隊多人協作,互相邏輯不干擾,這時候只能依賴隱式Intent跳轉,書寫麻煩,成功與否難以控制。
尤其是在專案演進的時候都會進行元件化開發,所以這裡網上有很多大神就研究出路由框架這麼一個東西,解決了上面的相應問題,這裡接觸的就是阿里巴巴開源的ARouter在GitHub上已經已經有3.+k的start了,相對來說應該比較穩定,所以讓我們開始吧!
2.ARouter的簡單使用
2.1首先是把ARouter引入到專案中去
- 首先在在module中配置相應的引數
defaultConfig {
.......
javaCompileOptions {
annotationProcessorOptions {
arguments = [ moduleName : project.getName() ]
}
}
}
- 然後配置api和compiler(這個也是在module中)
dependencies {
compile 'com.alibaba:arouter-api:x.x.x'
annotationProcessor 'com.alibaba:arouter-compiler:x.x.x'
...
}
- 上面是github上面寫的內容,但是有一點他沒有寫,但是就是一定要在專案的gradle中新增下面這段程式碼:
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' //路由需要
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
這句話一定要加上否則根本就跳轉不過去,具體為什麼我還真是不知道....
有了以上的內容就完成了基本的配置,就可以進行相應的跳轉了...
2.2程式碼中的簡單使用
- 在Application中初始化ARouter
/*初始化路由框架*/
ARouter.init(this);
- 首先要在你要跳轉的Activity(或者說是目標的Activity)新增註釋
@Route(path = "XXX/XXX")
這裡面要注意兩點首先這個註解裡面的內容必須是二級選單,這個在github上面有解釋,其次就是這個註解要寫在Activity的類上邊
- 通過程式碼進行跳轉(發起路由)
ARouter.getInstance().build("/XXX/XXX").navigation();
//跳轉中攜帶引數
ARouter.getInstance().build("/XXX/XXX")
.withLong("key", "value")
.withString("key", "value")
.navigation
這裡面的引數要和你要跳轉的Activity註解中的引數保持一致,當你傳遞引數的時候,你直接通過Intent去取就可以了.
通過以上步驟就能實現基本的跳轉傳遞引數了,但是身為有逼格的程式設計師我們怎麼能這樣就滿足了呢?
3.ARouter進階使用
3.1 利用Uri進行跳轉
Uri uri = Uri.parse("/test/activity");
ARouter.getInstance()
.build(uri)
.navigation();
3.2傳遞引數的獲取問題
當你傳遞引數的時候你可以通過Intent取獲取,當然也可以通過相應的註解進行獲取,就像下面這樣:
@Autowired(name = "xxx")
public String text;
這裡呢要注意,修飾符必須是public並且key值要相互對應.還要在目標的Activtiy中新增ARouter.getInstance().inject(this);才可以使用相應的值,否則取值的時候會失敗,但是不會報空指標.
3.3關於轉場動畫的跳轉處理
有沒有想過,之前在Activity跳轉的時候可以使用overridePendingTransition();,但是現在通過路由跳轉的話,沒有地方取設定動畫了,然後ARouter為我們想到了這個問題.
- 舊動畫:使用withTransition方法即可(相當於之前的overridePendingTransition()方法設定)
ARouter.getInstance().build(path).withTransition(R.anim_slide_in,R.anim_slide_out);
- 新動畫:使用withOptionsCompat方法即可(Android5.0新出的轉場動畫)
ActivityOptionsCompat compat = ActivityOptionsCompat.
makeScaleUpAnimation(view, view.getWidth() / 2, view.getHeight() / 2, 0, 0);
ARouter.getInstance().build("path").withOptionsCompat(compat)
.navigation();
3.4ARouter處理跳轉過程的結果
ARouter可以讓我們處理跳轉過程的結果,什麼用呢?就是你找到目標之後要進行什麼操作.
ARouter.getInstance().build("/module/jumpTestActivity2").navigation(null,
new NavigationCallback() {
@Override
public void onFound(Postcard postcard) {
// 找到目標後進行的操作
}
@Override
public void onLost(Postcard postcard) {
// 找不到目標進行的操作
}
});
補充說明:
在最新api中已經是四個方法了!
ARouter.getInstance().build("/test/activity").navigation(this, new NavigationCallback() {
@Override
public void onFound(Postcard postcard) {
//找到隊應的內容的時候
Log.e("done", "onFound: ");
}
@Override
public void onLost(Postcard postcard) {
//沒有找到對應的內容的時候
Log.e("done", "onLost: ");
}
@Override
public void onArrival(Postcard postcard) {
//跳轉成功
Log.e("done", "onArrival: ");
}
@Override
public void onInterrupt(Postcard postcard) {
//攔截操作
Log.e("done", "onInterrupt: ");
}
});
這裡可以在onLost中去處理"位置頁面"的跳轉結果,比如升級APP之類的話術.
3.5攜帶結果的Activity
ARouter.getInstance().build("/test/activity").navigation(this,10);
後面那個引數就是請求碼,別的和之前的都一樣.
3.6組的概念
在ARouter中有個組的概念,什麼意思呢?就是在構建路由請求的時候,可以指定分組.
其實這個分組本來就是有個你像path=/test/activity test就相當是分組,但是也可以使用group進行分組,像下面這段程式碼:
@Route(path = "/test/activity", group = "app")
這裡需要強調一下,如果你設定了相應的分組,那麼在進行跳轉的時候,一定要使用ARouter.getInstance().build(path, group)進行跳轉,否則無法找到相應的跳轉
3.7重寫跳轉URL實現重定向
可以重新定向你的URL地址
@Route(path = "/test/activity2")
public class PathReplaceServerImp implements PathReplaceService {
@Override
public String forString(String path) {
path = "/test/activity2";
return path;
}
@Override
public Uri forUri(Uri uri) {
return null;
}
@Override
public void init(Context context) {
Log.e("done", "init: 這裡是初始化的時候執行的方法");
}
}
這裡說明一下:上面得path一定要加上一個任意專案中出現得註解即可,如果專案中沒有出現得話會報空指標異常的.通過上面的程式碼,就可以更改專案中跳轉時候的path和URL地址了.
3.8ARouter攔截器
ARouter的攔截器可以在navigation的過程中攔截請求,並進行一系列的處理 ,是一種AOP的程式設計模式(應用場景為檢查登陸狀態等)要實現攔截器,首先我們需要實現IInterceptor介面,並使用Interceptor註解標記我們的攔截器,並傳入priority優先順序引數(數字越小,優先順序越高),其實攔截器就是實現了一個介面去進行回撥的!
public class TestInterceotor implements IInterceptor {
@Override
public void process(Postcard postcard, final InterceptorCallback callback) {
if (postcard.getPath().equals("/test/activity")) {
callback.onContinue(postcard);
} else {
callback.onContinue(postcard);
}
}
@Override
public void init(Context context) {
Log.e("done", "init: 初始化呼叫");
}
}
這裡說明幾點內容:
- 首先process這個方法是處理攔截內容的,這裡我判斷了一個相應的註解路由,如果跳轉的是相應的路徑,那麼進行攔截.
- 其次callback.onContinue(postcard)這個要注意,這句話的含義就是交由路由去處理,如果這裡不寫這句話的話,路由就終止了.
- init方法是全域性只執行一次,這裡為什麼這麼設計我也不知道,應該是用到相應的內容了吧!原諒我是一個菜鳥
- 如果你想加入相應的等級的話在類的上面加入如下註解@Interceptor(priority = 7)其實就是設定攔截器等級的,這裡為什麼又攔截器的等級呢?主要是為了讓攔截器一級一級的向下傳遞.這樣就有了多級的攔截器.
上面的內容只是簡單的用到了攔截器,但是理解起來畢竟又一些晦澀,當直接說讓你實現登陸的攔截,你怎麼實現,開始的時候我也覺得簡單,但是當自己寫的時候,我發現這個問題真不是看上去那麼簡單.這裡我先把內容攔截器的程式碼都放上,然後我在講解!
- 首次跳轉的邏輯
ARouter.getInstance().build("/test/activity").navigation(this, new NavCallback() {
@Override
public void onArrival(Postcard postcard) {
}
@Override
public void onInterrupt(Postcard postcard) {
Log.e(TAG, "onInterrupt: 這個方法是攔截器執行之後才執行的");
}
});
- 攔截器的程式碼:
@Interceptor(priority = 7)
public class TestInterceotor implements IInterceptor {
@Override
public void process(Postcard postcard, final InterceptorCallback callback) {
if (postcard.getPath().equals("/test/activity")) {
Log.e("done", "process: main2Activity");
if (APP.isLogin) {/*已經登陸*/
callback.onContinue(postcard);
} else {/*沒有登陸*/
ARouter.getInstance().build("/test/activity2")
.withString("name", postcard.getPath()).navigation();
}
Log.e("done", "process: 執行完了");
} else {
Log.e("done", "process: 這個方法什麼時候執行");
callback.onContinue(postcard);
}
}
@Override
public void init(Context context) {
Log.e("done", "init: 初始化呼叫");
}
}
- 模擬登陸的Activity
@Route(path = "/test/activity2")
public class Main3Activity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
ARouter.getInstance().inject(this);
}
public void click(View view) {
APP.isLogin = true;
ARouter.getInstance().build("/test/activity").navigation();
finish();
}
}
這裡第一次跳轉的時候,由於攔截器使得沒有登陸的邏輯就跳轉到了登陸頁面,之後我在登陸頁面模擬了一次登陸的操作,然後關閉這個頁面之前,我又重新跳轉了目標頁面,這次由於已經登陸了,所以會直接繼續執行跳轉了目標頁面.這裡說的挺簡單的,有一個回撥我還沒有搞清楚,onInterrupt這個回撥之後有什麼用,其實這裡也可以傳入一個欄位,然後跳轉的時候直接傳入這個欄位,這個欄位主要是儲存要跳轉的頁面的資料,之後就能直接跳轉了.這樣就解決了耦合的問題.
3.9在攔截器中新增額外的引數
@Route(path = "/test/activity", extras = 0;/*注意這裡是int型別的引數*/)
說明一下:這個是在目標的Activity頁面新增的額外引數,之後會在攔截器內生效.
總結
其實關於這個框架還有很多問題我沒有理解,但是基本的一些內容都已經講解了,其實接觸這個框架主要是當初看見元件化開發的時候,看到了這個框架,其實在專案中使用也可以,整體管理了跳轉.寫的挺亂的,感謝大家抽出寶貴時間來閱讀,有什麼不對的地方希望指正.
相關文章
- Android元件化專題 - 路由框架原理Android元件化路由框架
- Android路由框架AnnoRouter:使用Java介面來定義路由跳轉Android路由框架Java
- WMRouter:美團外賣Android開源路由框架Android路由框架
- 一個Android路由框架的誕生之路Android路由框架
- httprouter框架 (Gin使用的路由框架)HTTP框架路由
- AndroidRouter路由框架使用Android路由框架
- Flutter路由框架Fluro簡介Flutter路由框架
- ARouter路由框架原始碼解析路由框架原始碼
- gin框架post路由的使用框架路由
- Android元件化專題 - 路由框架進階模組間的業務通訊Android元件化路由框架
- http 框架的路由實現原理HTTP框架路由
- Flask框架(二):路由與藍圖Flask框架路由
- Flutter路由輕量級框架FRouterFlutter路由框架
- Gin 框架 - 安裝和路由配置框架路由
- Django框架之路由層彙總Django框架路由
- 元件和模組間Activity路由框架元件路由框架
- Android路由方案ARouter分析Android路由
- Android框架Android框架
- DIY 實現 ThinkPHP 核心框架 (三)路由PHP框架路由
- 前端框架擼起來——元件和路由前端框架元件路由
- Tornado框架03-路由系統框架路由
- nodejs express 框架解密4-路由NodeJSExpress框架解密路由
- 【Android】StateUi 框架AndroidUI框架
- android框架圖Android框架
- PHP DIY 系列------框架篇:3. 路由解析PHP框架路由
- Flutter從0開發一個路由框架Flutter路由框架
- API後端框架Godtail2-路由元件API後端框架GoAI路由元件
- nuxt框架中路由鑑權——Koa和SessionUX框架路由Session
- Android 路由設計最佳實踐Android路由
- 怎麼使用路由框架Fluro?Flutter的這個框架太優秀了!路由框架Flutter
- go的web框架gin的使用(七):多路由GoWeb框架路由
- Flask框架從入門到精通之路由(三)Flask框架路由
- 阿里巴巴開源路由框架 - ARouter 分析阿里路由框架
- 各種前端框架中的路由原理解析前端框架路由
- Android 常用框架集合Android框架
- Android框架淺析Android框架
- Android KitKat Print框架Android框架
- Android精通之OrmLite資料庫框架,Picasso框架,Okio框架,OKHttp框架AndroidORM資料庫框架HTTP