<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                文檔當前狀態:**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整個生命周期中都不會用到,所以服務只有被調用的時候才會觸發初始化操作
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看