文檔當前狀態:**beta0.4**
* [x] 選題收集:2017/11/21
* [x] 初稿整理:
* [ ] 補充校對:
* [ ] 入庫存檔:
---
[TOC]
---
上篇對模塊化實踐中 Gradle的配置做了簡單的說明,接下來會說明 如何在代碼中使用ARouter 來實現模塊化設計。主要會有以下兩個部分: ARouter的使用、常見問題說明;
作為一個正在更新的庫,沒有什么比官方文檔,能更好的了解他的使用。
[官方文檔README_CN](https://github.com/alibaba/ARouter/blob/master/README_CN.md
)
下面是一些使用簡要說明基于arouter-api:1.2.4、arouter-compiler:1.1.4:
#### 一、功能介紹
1. **支持直接解析標準URL進行跳轉,并自動注入參數到目標頁面中**
2. **支持多模塊工程使用**
3. **支持添加多個攔截器,自定義攔截順序**
4. **支持依賴注入,可單獨作為依賴注入框架使用**
5. **支持InstantRun**
6. **支持MultiDex**(Google方案)
7. 映射關系按組分類、多級管理,按需初始化
8. 支持用戶指定全局降級與局部降級策略
9. 頁面、攔截器、服務等組件均自動注冊到框架
10. 支持多種方式配置轉場動畫
11. 支持獲取Fragment
12. 完全支持Kotlin以及混編(配置見文末 其他#5)
#### 二、典型應用
1. 從外部URL映射到內部頁面,以及參數傳遞與解析
2. 跨模塊頁面跳轉,模塊間解耦
3. 攔截跳轉過程,處理登陸、埋點等邏輯
4. 跨模塊API調用,通過控制反轉來做組件解耦
#### 三、基礎功能
1. 添加依賴和配置
這是java的配置
``` gradle
android {
defaultConfig {
...
javaCompileOptions {
annotationProcessorOptions {
arguments = [ moduleName : project.getName() ]
}
}
}
}
dependencies {
// 替換成最新版本, 需要注意的是api
// 要與compiler匹配使用,均使用最新版可以保證兼容
compile 'com.alibaba:arouter-api:x.x.x'
annotationProcessor 'com.alibaba:arouter-compiler:x.x.x'
...
}
// 舊版本gradle插件(< 2.2),可以使用apt插件,配置方法見文末'其他#4'
// Kotlin配置參考文末'其他#5'
```
這是Kotlin的配置
```
// 可以參考 module-kotlin 模塊中的寫法
apply plugin: 'kotlin-kapt'
kapt {
arguments {
arg("moduleName", project.getName())
}
}
dependencies {
compile 'com.alibaba:arouter-api:x.x.x'
kapt 'com.alibaba:arouter-compiler:x.x.x'
...
}
```
2. 添加注解
``` java
// 在支持路由的頁面上添加注解(必選)
// 這里的路徑需要注意的是至少需要有兩級,/xx/xx
@Route(path = "/test/activity")
public class YourActivity extend Activity {
...
}
//為了更好關聯引用關系,使用靜態常量來代替常量
@Route(path = PathIndex.YouActivity)
public class YourActivity extend Activity {
...
}
```
這里需要重點說一下的就是,純粹使用@Route(path = "/test/activity"),這種字符串的樣式 去寫路徑,在查看相互引用關系會一團糟,你永遠不能快速 準確的知道 這個activity 到底被誰引用到,在榮耀的開發中,我們進行了一個簡單的方式,在中間共用層,建立一個存儲路由路徑目錄的常量類 PathIndex。
3. 初始化SDK
``` java
if (isDebug()) { // 這兩行必須寫在init之前,否則這些配置在init過程中將無效
ARouter.openLog(); // 打印日志
ARouter.openDebug(); // 開啟調試模式(如果在InstantRun模式下運行,必須開啟調試模式!線上版本需要關閉,否則有安全風險)
}
ARouter.init(mApplication); // 盡可能早,推薦在Application中初始化
```
4. 發起路由操作
``` java
// 1. 應用內簡單的跳轉(通過URL跳轉在'進階用法'中)
ARouter.getInstance().build("/test/activity").navigation();
// 2. 跳轉并攜帶參數
ARouter.getInstance().build("/test/1")
.withLong("key1", 666L)
.withString("key3", "888")
.withObject("key4", new Test("Jack", "Rose"))
.navigation();
```
5. 添加混淆規則(如果使用了Proguard)
```
-keep public class com.alibaba.android.arouter.routes.**{*;}
-keep class * implements com.alibaba.android.arouter.facade.template.ISyringe{*;}
# 如果使用了 byType 的方式獲取 Service,需添加下面規則,保護接口
-keep interface * implements com.alibaba.android.arouter.facade.template.IProvider
# 如果使用了 單類注入,即不定義接口實現 IProvider,需添加下面規則,保護實現
-keep class * implements com.alibaba.android.arouter.facade.template.IProvider
```
#### 四、進階用法
1. 通過URL跳轉
這個功能主要是點擊外部url鏈接時候,可以直接跳轉進原生的頁面,類型淘寶、京東、貼吧。
``` java
// 新建一個Activity用于監聽Schame事件,之后直接把url傳遞給ARouter即可
public class SchameFilterActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Uri uri = getIntent().getData();
ARouter.getInstance().build(uri).navigation();
finish();
}
}
```
AndroidManifest.xml
``` xml
<activity android:name=".activity.SchameFilterActivity">
<!-- Schame -->
<intent-filter>
<data
android:host="m.aliyun.com"
android:scheme="arouter"/>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>
</activity>
```
2. 解析URL中的參數
``` java
// 為每一個參數聲明一個字段,并使用 @Autowired 標注
// URL中不能傳遞Parcelable類型數據,通過ARouter api可以傳遞Parcelable對象
@Route(path = "/test/activity")
public class Test1Activity extends Activity {
@Autowired
public String name;
@Autowired
int age;
@Autowired(name = "girl") // 通過name來映射URL中的不同參數
boolean boy;
@Autowired
TestObj obj; // 支持解析自定義對象,URL中使用json傳遞
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ARouter.getInstance().inject(this);
// ARouter會自動對字段進行賦值,無需主動獲取
Log.d("param", name + age + boy);
}
}
// 如果需要傳遞自定義對象,需要實現 SerializationService,并使用@Route注解標注(方便用戶自行選擇序列化方式),例如:
@Route(path = "/service/json")
public class JsonServiceImpl implements SerializationService {
@Override
public void init(Context context) {
}
@Override
public <T> T json2Object(String text, Class<T> clazz) {
return JSON.parseObject(text, clazz);
}
@Override
public String object2Json(Object instance) {
return JSON.toJSONString(instance);
}
}
```
3. 聲明攔截器(攔截跳轉過程,面向切面編程)
``` java
// 比較經典的應用就是在跳轉過程中處理登陸事件,這樣就不需要在目標頁重復做登陸檢查
// 攔截器會在跳轉之間執行,多個攔截器會按優先級順序依次執行
@Interceptor(priority = 8, name = "測試用攔截器")
public class TestInterceptor implements IInterceptor {
@Override
public void process(Postcard postcard, InterceptorCallback callback) {
...
callback.onContinue(postcard); // 處理完成,交還控制權
// callback.onInterrupt(new RuntimeException("我覺得有點異常")); // 覺得有問題,中斷路由流程
// 以上兩種至少需要調用其中一種,否則不會繼續路由
}
@Override
public void init(Context context) {
// 攔截器的初始化,會在sdk初始化的時候調用該方法,僅會調用一次
}
}
```
4. 處理跳轉結果
``` java
// 使用兩個參數的navigation方法,可以獲取單次跳轉的結果
ARouter.getInstance().build("/test/1").navigation(this, new NavigationCallback() {
@Override
public void onFound(Postcard postcard) {
...
}
@Override
public void onLost(Postcard postcard) {
...
}
});
```
5. 自定義全局降級策略
主要是為了 沒有找到對應路由時候,給出相對友好的提示,一般提供一個H5頁面即可
``` java
// 實現DegradeService接口,并加上一個Path內容任意的注解即可
@Route(path = "/xxx/xxx")
public class DegradeServiceImpl implements DegradeService {
@Override
public void onLost(Context context, Postcard postcard) {
// do something.
}
@Override
public void init(Context context) {
}
}
```
6. 為目標頁面聲明更多信息
``` java
// 我們經常需要在目標頁面中配置一些屬性,比方說"是否需要登陸"之類的
// 可以通過 Route 注解中的 extras 屬性進行擴展,這個屬性是一個 int值,換句話說,單個int有4字節,也就是32位,可以配置32個開關
// 剩下的可以自行發揮,通過字節操作可以標識32個開關,通過開關標記目標頁面的一些屬性,在攔截器中可以拿到這個標記進行業務邏輯判斷
@Route(path = "/test/activity", extras = Consts.XXXX)
```
7. 通過依賴注入解耦:服務管理(一) 暴露服務
``` java
// 聲明接口,其他組件通過接口來調用服務
public interface HelloService extends IProvider {
String sayHello(String name);
}
// 實現接口
@Route(path = "/service/hello", name = "測試服務")
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello(String name) {
return "hello, " + name;
}
@Override
public void init(Context context) {
}
}
```
9. 通過依賴注入解耦:服務管理(二) 發現服務
``` java
public class Test {
@Autowired
HelloService helloService;
@Autowired(name = "/service/hello")
HelloService helloService2;
HelloService helloService3;
HelloService helloService4;
public Test() {
ARouter.getInstance().inject(this);
}
public void testService() {
// 1. (推薦)使用依賴注入的方式發現服務,通過注解標注字段,即可使用,無需主動獲取
// Autowired注解中標注name之后,將會使用byName的方式注入對應的字段,不設置name屬性,會默認使用byType的方式發現服務(當同一接口有多個實現的時候,必須使用byName的方式發現服務)
helloService.sayHello("Vergil");
helloService2.sayHello("Vergil");
// 2. 使用依賴查找的方式發現服務,主動去發現服務并使用,下面兩種方式分別是byName和byType
helloService3 = ARouter.getInstance().navigation(HelloService.class);
helloService4 = (HelloService) ARouter.getInstance().build("/service/hello").navigation();
helloService3.sayHello("Vergil");
helloService4.sayHello("Vergil");
}
}
```
#### 五、更多功能
1. 初始化中的其他設置
``` java
ARouter.openLog(); // 開啟日志
ARouter.openDebug(); // 使用InstantRun的時候,需要打開該開關,上線之后關閉,否則有安全風險
ARouter.printStackTrace(); // 打印日志的時候打印線程堆棧
```
2. 詳細的API說明
``` java
// 構建標準的路由請求(會自動分組)
ARouter.getInstance().build("/home/main").navigation();
// (不推薦使用,作者已經將其標記為"過時")構建標準的路由請求,并指定分組
//ARouter.getInstance().build("/home/main", "ap").navigation();
// 構建標準的路由請求,通過Uri直接解析
Uri uri;
ARouter.getInstance().build(uri).navigation();
// 構建標準的路由請求,startActivityForResult
// navigation的第一個參數必須是Activity,第二個參數則是RequestCode
ARouter.getInstance().build("/home/main", "ap").navigation(this, 5);
// 直接傳遞Bundle
Bundle params = new Bundle();
ARouter.getInstance()
.build("/home/main")
.with(params)
.navigation();
// 指定Flag
ARouter.getInstance()
.build("/home/main")
.withFlags();
.navigation();
// 獲取Fragment
Fragment fragment = (Fragment) ARouter.getInstance().build("/test/fragment").navigation();
// 對象傳遞
ARouter.getInstance()
.withObject("key", new TestObj("Jack", "Rose"))
.navigation();
// 覺得接口不夠多,可以直接拿出Bundle賦值
ARouter.getInstance()
.build("/home/main")
.getExtra();
// 轉場動畫(常規方式)
ARouter.getInstance()
.build("/test/activity2")
.withTransition(R.anim.slide_in_bottom, R.anim.slide_out_bottom)
.navigation(this);
// 轉場動畫(API16+)
ActivityOptionsCompat compat = ActivityOptionsCompat.
makeScaleUpAnimation(v, v.getWidth() / 2, v.getHeight() / 2, 0, 0);
// ps. makeSceneTransitionAnimation 使用共享元素的時候,需要在navigation方法中傳入當前Activity
ARouter.getInstance()
.build("/test/activity2")
.withOptionsCompat(compat)
.navigation();
// 使用綠色通道(跳過所有的攔截器)
ARouter.getInstance().build("/home/main").greenChannel().navigation();
// 使用自己的日志工具打印日志
ARouter.setLogger();
```
3. 獲取原始的URI
``` java
String uriStr = getIntent().getStringExtra(ARouter.RAW_URI);
```
4. 重寫跳轉URL
``` java
// 實現PathReplaceService接口,并加上一個Path內容任意的注解即可
@Route(path = "/xxx/xxx") // 必須標明注解
public class PathReplaceServiceImpl implements PathReplaceService {
/**
* For normal path.
*
* @param path raw path
*/
String forString(String path) {
return path; // 按照一定的規則處理之后返回處理后的結果
}
/**
* For uri type.
*
* @param uri raw uri
*/
Uri forUri(Uri uri) {
return url; // 按照一定的規則處理之后返回處理后的結果
}
}
```
#### 六、其他
1. 路由中的分組概念
- SDK中針對所有的路徑(/test/1 /test/2)進行分組,分組只有在分組中的某一個路徑第一次被訪問的時候,該分組才會被初始化
- (不推薦,已標記過時)可以通過 @Route 注解主動指定分組,否則使用路徑中第一段字符串(/*/)作為分組
- 注意:一旦主動指定分組之后,應用內路由需要使用 ARouter.getInstance().build(path, group) 進行跳轉,手動指定分組,否則無法找到
``` java
@Route(path = "/test/1", group = "app")
```
2. 攔截器和服務的異同
- 攔截器和服務所需要實現的接口不同,但是結構類似,都存在 init(Context context) 方法,但是兩者的調用時機不同
- 攔截器因為其特殊性,會被任何一次路由所觸發,攔截器會在ARouter初始化的時候異步初始化,如果第一次路由的時候攔截器還沒有初始化結束,路由會等待,直到初始化完成。
- 服務沒有該限制,某一服務可能在App整個生命周期中都不會用到,所以服務只有被調用的時候才會觸發初始化操作
- 0-發現
- AndroidInterview-Q-A
- Android能讓你少走彎路的干貨整理
- LearningNotes
- temp
- temp11
- 部分地址
- 0-待辦任務
- 待補充列表
- 0-未分類
- AndroidView事件分發與滑動沖突處理
- Spannable
- 事件分發機制詳解
- 1-Java
- 1-Java-01基礎
- 未歸檔
- 你應該知道的JDK知識
- 集合框架
- 1-Java-04合集
- Java之旅0
- Java之旅
- JAVA之旅01
- JAVA之旅02
- JAVA之旅03
- JAVA之旅04
- JAVA之旅05
- JAVA之旅06
- JAVA之旅07
- JAVA之旅08
- JAVA之旅09
- java之旅1
- JAVA之旅10
- JAVA之旅11
- JAVA之旅12
- JAVA之旅13
- JAVA之旅14
- JAVA之旅15
- JAVA之旅16
- JAVA之旅17
- JAVA之旅18
- JAVA之旅19
- java之旅2
- JAVA之旅20
- JAVA之旅21
- JAVA之旅22
- JAVA之旅23
- JAVA之旅24
- JAVA之旅25
- JAVA之旅26
- JAVA之旅27
- JAVA之旅28
- JAVA之旅29
- java之旅3
- JAVA之旅30
- JAVA之旅31
- JAVA之旅32
- JAVA之旅33
- JAVA之旅34
- JAVA之旅35
- 1-Java-05辨析
- HashMapArrayMap
- Java8新特性
- Java8接口默認方法
- 圖解HashMap(1)
- 圖解HashMap(2)
- 2-Android
- 2-Android-1-基礎
- View繪制流程
- 事件分發
- AndroidView的事件分發機制和滑動沖突解決
- 自定義View基礎
- 1-安卓自定義View基礎-坐標系
- 2-安卓自定義View基礎-角度弧度
- 3-安卓自定義View基礎-顏色
- 自定義View進階
- 1-安卓自定義View進階-分類和流程
- 10-安卓自定義View進階-Matrix詳解
- 11-安卓自定義View進階-MatrixCamera
- 12-安卓自定義View進階-事件分發機制原理
- 13-安卓自定義View進階-事件分發機制詳解
- 14-安卓自定義View進階-MotionEvent詳解
- 15-安卓自定義View進階-特殊形狀控件事件處理方案
- 16-安卓自定義View進階-多點觸控詳解
- 17-安卓自定義View進階-手勢檢測GestureDetector
- 2-安卓自定義View進階-繪制基本圖形
- 3-安卓自定義View進階-畫布操作
- 4-安卓自定義View進階-圖片文字
- 5-安卓自定義View進階-Path基本操作
- 6-安卓自定義View進階-貝塞爾曲線
- 7-安卓自定義View進階-Path完結篇偽
- 8-安卓自定義View進階-Path玩出花樣PathMeasure
- 9-安卓自定義View進階-Matrix原理
- 通用類介紹
- Application
- 2-Android-2-使用
- 2-Android-02控件
- ViewGroup
- ConstraintLayout
- CoordinatorLayout
- 2-Android-03三方使用
- Dagger2
- Dagger2圖文完全教程
- Dagger2最清晰的使用教程
- Dagger2讓你愛不釋手-終結篇
- Dagger2讓你愛不釋手-重點概念講解、融合篇
- dagger2讓你愛不釋手:基礎依賴注入框架篇
- 閱讀筆記
- Glide
- Google推薦的圖片加載庫Glide:最新版使用指南(含新特性)
- rxjava
- 這可能是最好的RxJava2.x入門教程完結版
- 這可能是最好的RxJava2.x入門教程(一)
- 這可能是最好的RxJava2.x入門教程(三)
- 這可能是最好的RxJava2.x入門教程(二)
- 這可能是最好的RxJava2.x入門教程(五)
- 這可能是最好的RxJava2.x入門教程(四)
- 2-Android-3-優化
- 優化概況
- 各種優化
- Android端秒開優化
- apk大小優化
- 內存分析
- 混淆
- 2-Android-4-工具
- adb命令
- 一鍵分析Android的BugReport
- 版本控制
- git
- git章節簡述
- 2-Android-5-源碼
- HandlerThread 源碼分析
- IntentService的使用和源碼分析
- 2-Android-9-辨析
- LRU算法
- 什么是Bitmap
- 常見圖片壓縮方式
- 3-Kotlin
- Kotlin使用筆記1-草稿
- Kotlin使用筆記2
- kotlin特性草稿
- Kotlin草稿-Delegation
- Kotlin草稿-Field
- Kotlin草稿-object
- 4-JavaScript
- 5-Python
- 6-Other
- Git
- Gradle
- Android中ProGuard配置和總結
- gradle使用筆記
- Nexus私服搭建
- 編譯提速最佳實踐
- 7-設計模式與架構
- 組件化
- 組件化探索(OKR)
- 1-參考列表
- 2-1-組件化概述
- 2-2-gradle配置
- 2-3-代碼編寫
- 2-4-常見問題
- 2-9-值得一讀
- 8-數據結構與算法
- 0臨時文件
- 漢諾塔
- 8-數據-1數據結構
- HashMap
- HashMap、Hashtable、HashSet 和 ConcurrentHashMap 的比較
- 遲到一年HashMap解讀
- 8-數據-2算法
- 1個就夠了
- Java常用排序算法(必須掌握的8大排序算法)
- 常用排序算法總結(性能+代碼)
- 必須知道的八大種排序算法(java實現)
- 9-職業
- 閱讀
- 書單
- 面試
- 面試-01-java
- Java面試題全集駱昊(上)
- Java面試題全集駱昊(下)
- Java面試題全集駱昊(中)
- 面試-02-android
- 40道Android面試題
- 面試-03-開源源碼
- Android圖片加載框架最全解析(二),從源碼的角度理解Glide的執行流程
- 面試-07-設計模式
- 面試-08-算法
- 面試-09-其他
- SUMMARY
- 版權說明
- temp111