ARouter-幫助 Android App 進(jìn)行組件化改造的路由框架

github地址:https://github.com/alibaba/ARouter

展示

Demo apk下載猛频、Demo Gif

一辕万、功能介紹

  1. 支持直接解析標(biāo)準(zhǔn)URL進(jìn)行跳轉(zhuǎn),并自動(dòng)注入?yún)?shù)到目標(biāo)頁(yè)面中
  2. 支持多模塊工程使用
  3. 支持添加多個(gè)攔截器儡司,自定義攔截順序
  4. 支持依賴注入娱挨,可單獨(dú)作為依賴注入框架使用
  5. 支持InstantRun
  6. 支持MultiDex(Google方案)
  7. 映射關(guān)系按組分類、多級(jí)管理捕犬,按需初始化
  8. 支持用戶指定全局降級(jí)與局部降級(jí)策略
  9. 頁(yè)面跷坝、攔截器酵镜、服務(wù)等組件均自動(dòng)注冊(cè)到框架
  10. 支持多種方式配置轉(zhuǎn)場(chǎng)動(dòng)畫
  11. 支持獲取Fragment
  12. 完全支持Kotlin以及混編(配置見(jiàn)文末 其他#5)
  13. 支持第三方 App 加固(使用 arouter-register 實(shí)現(xiàn)自動(dòng)注冊(cè))
  14. 支持生成路由文檔
  15. 提供 IDE 插件便捷的關(guān)聯(lián)路徑和目標(biāo)類

二、典型應(yīng)用

  1. 從外部URL映射到內(nèi)部頁(yè)面柴钻,以及參數(shù)傳遞與解析
  2. 跨模塊頁(yè)面跳轉(zhuǎn)淮韭,模塊間解耦
  3. 攔截跳轉(zhuǎn)過(guò)程,處理登陸贴届、埋點(diǎn)等邏輯
  4. 跨模塊API調(diào)用缸濒,通過(guò)控制反轉(zhuǎn)來(lái)做組件解耦

三、基礎(chǔ)功能

  1. 添加依賴和配置

    android {
        defaultConfig {
            ...
            javaCompileOptions {
                annotationProcessorOptions {
                    arguments = [AROUTER_MODULE_NAME: 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插件斩跌,配置方法見(jiàn)文末'其他#4'
    // Kotlin配置參考文末'其他#5'
    
  2. 添加注解

    // 在支持路由的頁(yè)面上添加注解(必選)
    // 這里的路徑需要注意的是至少需要有兩級(jí)绍些,/xx/xx
    @Route(path = "/test/activity")
    public class YourActivity extend Activity {
        ...
    }
    
  3. 初始化SDK

    if (isDebug()) {           // 這兩行必須寫在init之前,否則這些配置在init過(guò)程中將無(wú)效
        ARouter.openLog();     // 打印日志
        ARouter.openDebug();   // 開(kāi)啟調(diào)試模式(如果在InstantRun模式下運(yùn)行耀鸦,必須開(kāi)啟調(diào)試模式柬批!線上版本需要關(guān)閉,否則有安全風(fēng)險(xiǎn))
    }
    ARouter.init(mApplication); // 盡可能早,推薦在Application中初始化
    
  4. 發(fā)起路由操作

    // 1\. 應(yīng)用內(nèi)簡(jiǎn)單的跳轉(zhuǎn)(通過(guò)URL跳轉(zhuǎn)在'進(jìn)階用法'中)
    ARouter.getInstance().build("/test/activity").navigation();
    
    // 2\. 跳轉(zhuǎn)并攜帶參數(shù)
    ARouter.getInstance().build("/test/1")
                .withLong("key1", 666L)
                .withString("key3", "888")
                .withObject("key4", new Test("Jack", "Rose"))
                .navigation();
    
  5. 添加混淆規(guī)則(如果使用了Proguard)

    -keep public class com.alibaba.android.arouter.routes.**{*;}
    -keep public class com.alibaba.android.arouter.facade.**{*;}
    -keep class * implements com.alibaba.android.arouter.facade.template.ISyringe{*;}
    
    # 如果使用了 byType 的方式獲取 Service袖订,需添加下面規(guī)則氮帐,保護(hù)接口
    -keep interface * implements com.alibaba.android.arouter.facade.template.IProvider
    
    # 如果使用了 單類注入,即不定義接口實(shí)現(xiàn) IProvider洛姑,需添加下面規(guī)則上沐,保護(hù)實(shí)現(xiàn)
    # -keep class * implements com.alibaba.android.arouter.facade.template.IProvider
    
    
  6. 使用 Gradle 插件實(shí)現(xiàn)路由表的自動(dòng)加載 (可選)

    apply plugin: 'com.alibaba.arouter'
    
    buildscript {
        repositories {
            jcenter()
        }
    
        dependencies {
            classpath "com.alibaba:arouter-register:?"
        }
    }
    

    可選使用,通過(guò) ARouter 提供的注冊(cè)插件進(jìn)行路由表的自動(dòng)加載(power by AutoRegister)楞艾, 默認(rèn)通過(guò)掃描 dex 的方式 進(jìn)行加載通過(guò) gradle 插件進(jìn)行自動(dòng)注冊(cè)可以縮短初始化時(shí)間解決應(yīng)用加固導(dǎo)致無(wú)法直接訪問(wèn) dex 文件参咙,初始化失敗的問(wèn)題,需要注意的是硫眯,該插件必須搭配 api 1.3.0 以上版本使用蕴侧!

  7. 使用 IDE 插件導(dǎo)航到目標(biāo)類 (可選)

    在 Android Studio 插件市場(chǎng)中搜索 ARouter Helper, 或者直接下載文檔上方 最新版本 中列出的 arouter-idea-plugin zip 安裝包手動(dòng)安裝,安裝后 插件無(wú)任何設(shè)置两入,可以在跳轉(zhuǎn)代碼的行首找到一個(gè)圖標(biāo) ([圖片上傳失敗...(image-673a43-1584713198828)] ) 點(diǎn)擊該圖標(biāo)净宵,即可跳轉(zhuǎn)到標(biāo)識(shí)了代碼中路徑的目標(biāo)類

四、進(jìn)階用法

  1. 通過(guò)URL跳轉(zhuǎn)

    // 新建一個(gè)Activity用于監(jiān)聽(tīng)Scheme事件,之后直接把url傳遞給ARouter即可
    public class SchemeFilterActivity extends Activity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        Uri uri = getIntent().getData();
        ARouter.getInstance().build(uri).navigation();
        finish();
        }
    }
    

    AndroidManifest.xml

    <activity android:name=".activity.SchemeFilterActivity">
        <!-- Scheme -->
        <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. 解析參數(shù)

    // 為每一個(gè)參數(shù)聲明一個(gè)字段裹纳,并使用 @Autowired 標(biāo)注
    // URL中不能傳遞Parcelable類型數(shù)據(jù)择葡,通過(guò)ARouter api可以傳遞Parcelable對(duì)象
    @Route(path = "/test/activity")
    public class Test1Activity extends Activity {
        @Autowired
        public String name;
        @Autowired
        int age;
    
        // 通過(guò)name來(lái)映射URL中的不同參數(shù)
        @Autowired(name = "girl") 
        boolean boy;
    
        // 支持解析自定義對(duì)象痘括,URL中使用json傳遞
        @Autowired
        TestObj obj;      
    
        // 使用 withObject 傳遞 List 和 Map 的實(shí)現(xiàn)了
        // Serializable 接口的實(shí)現(xiàn)類(ArrayList/HashMap)
        // 的時(shí)候密任,接收該對(duì)象的地方不能標(biāo)注具體的實(shí)現(xiàn)類類型
        // 應(yīng)僅標(biāo)注為 List 或 Map,否則會(huì)影響序列化中類型
        // 的判斷, 其他類似情況需要同樣處理        
        @Autowired
        List<TestObj> list;
        @Autowired
        Map<String, List<TestObj>> map;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ARouter.getInstance().inject(this);
    
        // ARouter會(huì)自動(dòng)對(duì)字段進(jìn)行賦值果漾,無(wú)需主動(dòng)獲取
        Log.d("param", name + age + boy);
        }
    }
    
    // 如果需要傳遞自定義對(duì)象她我,新建一個(gè)類(并非自定義對(duì)象類)虹曙,然后實(shí)現(xiàn) SerializationService,并使用@Route注解標(biāo)注(方便用戶自行選擇序列化方式)迫横,例如:
    @Route(path = "/yourservicegroupname/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. 聲明攔截器(攔截跳轉(zhuǎn)過(guò)程,面向切面編程)

    // 比較經(jīng)典的應(yīng)用就是在跳轉(zhuǎn)過(guò)程中處理登陸事件酝碳,這樣就不需要在目標(biāo)頁(yè)重復(fù)做登陸檢查
    // 攔截器會(huì)在跳轉(zhuǎn)之間執(zhí)行矾踱,多個(gè)攔截器會(huì)按優(yōu)先級(jí)順序依次執(zhí)行
    @Interceptor(priority = 8, name = "測(cè)試用攔截器")
    public class TestInterceptor implements IInterceptor {
        @Override
        public void process(Postcard postcard, InterceptorCallback callback) {
        ...
        callback.onContinue(postcard);  // 處理完成,交還控制權(quán)
        // callback.onInterrupt(new RuntimeException("我覺(jué)得有點(diǎn)異常"));      // 覺(jué)得有問(wèn)題疏哗,中斷路由流程
    
        // 以上兩種至少需要調(diào)用其中一種呛讲,否則不會(huì)繼續(xù)路由
        }
    
        @Override
        public void init(Context context) {
        // 攔截器的初始化,會(huì)在sdk初始化的時(shí)候調(diào)用該方法返奉,僅會(huì)調(diào)用一次
        }
    }
    
  4. 處理跳轉(zhuǎn)結(jié)果

    // 使用兩個(gè)參數(shù)的navigation方法贝搁,可以獲取單次跳轉(zhuǎn)的結(jié)果
    ARouter.getInstance().build("/test/1").navigation(this, new NavigationCallback() {
        @Override
        public void onFound(Postcard postcard) {
        ...
        }
    
        @Override
        public void onLost(Postcard postcard) {
        ...
        }
    });
    
  5. 自定義全局降級(jí)策略

    // 實(shí)現(xiàn)DegradeService接口,并加上一個(gè)Path內(nèi)容任意的注解即可
    @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. 為目標(biāo)頁(yè)面聲明更多信息

    // 我們經(jīng)常需要在目標(biāo)頁(yè)面中配置一些屬性芽偏,比方說(shuō)"是否需要登陸"之類的
    // 可以通過(guò) Route 注解中的 extras 屬性進(jìn)行擴(kuò)展雷逆,這個(gè)屬性是一個(gè) int值,換句話說(shuō)污尉,單個(gè)int有4字節(jié)膀哲,也就是32位,可以配置32個(gè)開(kāi)關(guān)
    // 剩下的可以自行發(fā)揮被碗,通過(guò)字節(jié)操作可以標(biāo)識(shí)32個(gè)開(kāi)關(guān)某宪,通過(guò)開(kāi)關(guān)標(biāo)記目標(biāo)頁(yè)面的一些屬性,在攔截器中可以拿到這個(gè)標(biāo)記進(jìn)行業(yè)務(wù)邏輯判斷
    @Route(path = "/test/activity", extras = Consts.XXXX)
    
  7. 通過(guò)依賴注入解耦:服務(wù)管理(一) 暴露服務(wù)

    // 聲明接口,其他組件通過(guò)接口來(lái)調(diào)用服務(wù)
    public interface HelloService extends IProvider {
        String sayHello(String name);
    }
    
    // 實(shí)現(xiàn)接口
    @Route(path = "/yourservicegroupname/hello", name = "測(cè)試服務(wù)")
    public class HelloServiceImpl implements HelloService {
    
        @Override
        public String sayHello(String name) {
        return "hello, " + name;
        }
    
        @Override
        public void init(Context context) {
    
        }
    }
    
  8. 通過(guò)依賴注入解耦:服務(wù)管理(二) 發(fā)現(xiàn)服務(wù)

    public class Test {
        @Autowired
        HelloService helloService;
    
        @Autowired(name = "/yourservicegroupname/hello")
        HelloService helloService2;
    
        HelloService helloService3;
    
        HelloService helloService4;
    
        public Test() {
        ARouter.getInstance().inject(this);
        }
    
        public void testService() {
        // 1\. (推薦)使用依賴注入的方式發(fā)現(xiàn)服務(wù),通過(guò)注解標(biāo)注字段,即可使用锐朴,無(wú)需主動(dòng)獲取
        // Autowired注解中標(biāo)注name之后兴喂,將會(huì)使用byName的方式注入對(duì)應(yīng)的字段,不設(shè)置name屬性焚志,會(huì)默認(rèn)使用byType的方式發(fā)現(xiàn)服務(wù)(當(dāng)同一接口有多個(gè)實(shí)現(xiàn)的時(shí)候瞻想,必須使用byName的方式發(fā)現(xiàn)服務(wù))
        helloService.sayHello("Vergil");
        helloService2.sayHello("Vergil");
    
        // 2\. 使用依賴查找的方式發(fā)現(xiàn)服務(wù),主動(dòng)去發(fā)現(xiàn)服務(wù)并使用娩嚼,下面兩種方式分別是byName和byType
        helloService3 = ARouter.getInstance().navigation(HelloService.class);
        helloService4 = (HelloService) ARouter.getInstance().build("/yourservicegroupname/hello").navigation();
        helloService3.sayHello("Vergil");
        helloService4.sayHello("Vergil");
        }
    }
    
  9. 預(yù)處理服務(wù)

    // 實(shí)現(xiàn) PretreatmentService 接口蘑险,并加上一個(gè)Path內(nèi)容任意的注解即可
    @Route(path = "/xxx/xxx")
    public class PretreatmentServiceImpl implements PretreatmentService {
        @Override
        public boolean onPretreatment(Context context, Postcard postcard) {
            // 跳轉(zhuǎn)前預(yù)處理,如果需要自行處理跳轉(zhuǎn)岳悟,該方法返回 false 即可
        }
    
        @Override
        public void init(Context context) {
    
        }
    }
    

五佃迄、更多功能

  1. 初始化中的其他設(shè)置

    ARouter.openLog(); // 開(kāi)啟日志
    ARouter.openDebug(); // 使用InstantRun的時(shí)候,需要打開(kāi)該開(kāi)關(guān)贵少,上線之后關(guān)閉呵俏,否則有安全風(fēng)險(xiǎn)
    ARouter.printStackTrace(); // 打印日志的時(shí)候打印線程堆棧
    
  2. 詳細(xì)的API說(shuō)明

    // 構(gòu)建標(biāo)準(zhǔn)的路由請(qǐng)求
    ARouter.getInstance().build("/home/main").navigation();
    
    // 構(gòu)建標(biāo)準(zhǔn)的路由請(qǐng)求,并指定分組
    ARouter.getInstance().build("/home/main", "ap").navigation();
    
    // 構(gòu)建標(biāo)準(zhǔn)的路由請(qǐng)求滔灶,通過(guò)Uri直接解析
    Uri uri;
    ARouter.getInstance().build(uri).navigation();
    
    // 構(gòu)建標(biāo)準(zhǔn)的路由請(qǐng)求普碎,startActivityForResult
    // navigation的第一個(gè)參數(shù)必須是Activity,第二個(gè)參數(shù)則是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();
    
    // 對(duì)象傳遞
    ARouter.getInstance()
        .withObject("key", new TestObj("Jack", "Rose"))
        .navigation();
    
    // 覺(jué)得接口不夠多录平,可以直接拿出Bundle賦值
    ARouter.getInstance()
            .build("/home/main")
            .getExtra();
    
    // 轉(zhuǎn)場(chǎng)動(dòng)畫(常規(guī)方式)
    ARouter.getInstance()
        .build("/test/activity2")
        .withTransition(R.anim.slide_in_bottom, R.anim.slide_out_bottom)
        .navigation(this);
    
    // 轉(zhuǎn)場(chǎng)動(dòng)畫(API16+)
    ActivityOptionsCompat compat = ActivityOptionsCompat.
        makeScaleUpAnimation(v, v.getWidth() / 2, v.getHeight() / 2, 0, 0);
    
    // ps. makeSceneTransitionAnimation 使用共享元素的時(shí)候麻车,需要在navigation方法中傳入當(dāng)前Activity
    
    ARouter.getInstance()
        .build("/test/activity2")
        .withOptionsCompat(compat)
        .navigation();
    
    // 使用綠色通道(跳過(guò)所有的攔截器)
    ARouter.getInstance().build("/home/main").greenChannel().navigation();
    
    // 使用自己的日志工具打印日志
    ARouter.setLogger();
    
    // 使用自己提供的線程池
    ARouter.setExecutor();
    
  3. 獲取原始的URI

    String uriStr = getIntent().getStringExtra(ARouter.RAW_URI);
    
  4. 重寫跳轉(zhuǎn)URL

    // 實(shí)現(xiàn)PathReplaceService接口缀皱,并加上一個(gè)Path內(nèi)容任意的注解即可
    @Route(path = "/xxx/xxx") // 必須標(biāo)明注解
    public class PathReplaceServiceImpl implements PathReplaceService {
        /**
        * For normal path.
        *
        * @param path raw path
        */
        String forString(String path) {
        return path;    // 按照一定的規(guī)則處理之后返回處理后的結(jié)果
        }
    
    /**
        * For uri type.
        *
        * @param uri raw uri
        */
    Uri forUri(Uri uri) {
        return url;    // 按照一定的規(guī)則處理之后返回處理后的結(jié)果
    }
    }
    
  5. 生成路由文檔

    // 更新 build.gradle, 添加參數(shù) AROUTER_GENERATE_DOC = enable
    // 生成的文檔路徑 : build/generated/source/apt/(debug or release)/com/alibaba/android/arouter/docs/arouter-map-of-${moduleName}.json
    android {
        defaultConfig {
            ...
            javaCompileOptions {
                annotationProcessorOptions {
                    arguments = [AROUTER_MODULE_NAME: project.getName(), AROUTER_GENERATE_DOC: "enable"]
                }
            }
        }
    }
    

六、其他

  1. 路由中的分組概念

    • SDK中針對(duì)所有的路徑(/test/1 /test/2)進(jìn)行分組动猬,分組只有在分組中的某一個(gè)路徑第一次被訪問(wèn)的時(shí)候啤斗,該分組才會(huì)被初始化
    • 可以通過(guò) @Route 注解主動(dòng)指定分組,否則使用路徑中第一段字符串(/*/)作為分組
    • 注意:一旦主動(dòng)指定分組之后赁咙,應(yīng)用內(nèi)路由需要使用 ARouter.getInstance().build(path, group) 進(jìn)行跳轉(zhuǎn)钮莲,手動(dòng)指定分組,否則無(wú)法找到
    @Route(path = "/test/1", group = "app")
    
  2. 攔截器和服務(wù)的異同

    • 攔截器和服務(wù)所需要實(shí)現(xiàn)的接口不同彼水,但是結(jié)構(gòu)類似崔拥,都存在 init(Context context) 方法,但是兩者的調(diào)用時(shí)機(jī)不同
    • 攔截器因?yàn)槠涮厥庑苑锔玻瑫?huì)被任何一次路由所觸發(fā)链瓦,攔截器會(huì)在ARouter初始化的時(shí)候異步初始化,如果第一次路由的時(shí)候攔截器還沒(méi)有初始化結(jié)束叛赚,路由會(huì)等待,直到初始化完成稽揭。
    • 服務(wù)沒(méi)有該限制俺附,某一服務(wù)可能在App整個(gè)生命周期中都不會(huì)用到,所以服務(wù)只有被調(diào)用的時(shí)候才會(huì)觸發(fā)初始化操作
  3. 舊版本gradle插件的配置方式

    apply plugin: 'com.neenbedankt.android-apt'
    
    buildscript {
        repositories {
        jcenter()
        }
    
        dependencies {
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'
        }
    }
    
    apt {
        arguments {
        AROUTER_MODULE_NAME project.getName();
        }
    }
    
    dependencies {
        compile 'com.alibaba:arouter-api:x.x.x'
        apt 'com.alibaba:arouter-compiler:x.x.x'
        ...
    }
    
  4. Kotlin項(xiàng)目中的配置方式

    // 可以參考 module-kotlin 模塊中的寫法
    apply plugin: 'kotlin-kapt'
    
    kapt {
        arguments {
            arg("AROUTER_MODULE_NAME", project.getName())
        }
    }
    
    dependencies {
        compile 'com.alibaba:arouter-api:x.x.x'
        kapt 'com.alibaba:arouter-compiler:x.x.x'
        ...
    }
    
    

七溪掀、Q&A

  1. "W/ARouter::: ARouter::No postcard![ ]"

    這個(gè)Log正常的情況下也會(huì)打印出來(lái)事镣,如果您的代碼中沒(méi)有實(shí)現(xiàn)DegradeService和PathReplaceService的話,因?yàn)锳Router本身的一些功能也依賴 自己提供的Service管理功能揪胃,ARouter在跳轉(zhuǎn)的時(shí)候會(huì)嘗試尋找用戶實(shí)現(xiàn)的PathReplaceService璃哟,用于對(duì)路徑進(jìn)行重寫(可選功能),所以如果您沒(méi)有 實(shí)現(xiàn)這個(gè)服務(wù)的話喊递,也會(huì)拋出這個(gè)日志

    推薦在app中實(shí)現(xiàn)DegradeService随闪、PathReplaceService

  2. "W/ARouter::: ARouter::There is no route match the path [/xxx/xxx], in group [xxx][ ]"

    • 通常來(lái)說(shuō)這種情況是沒(méi)有找到目標(biāo)頁(yè)面,目標(biāo)不存在
    • 如果這個(gè)頁(yè)面是存在的骚勘,那么您可以按照下面的步驟進(jìn)行排查
      1. 檢查目標(biāo)頁(yè)面的注解是否配置正確铐伴,正確的注解形式應(yīng)該是 (@Route(path="/test/test"), 如沒(méi)有特殊需求,請(qǐng)勿指定group字段俏讹,廢棄功能)
      2. 檢查目標(biāo)頁(yè)面所在的模塊的gradle腳本中是否依賴了 arouter-compiler sdk (需要注意的是当宴,要使用apt依賴,而不是compile關(guān)鍵字依賴)
      3. 檢查編譯打包日志泽疆,是否出現(xiàn)了形如 ARouter::?Compiler >>> xxxxx 的日志户矢,日志中會(huì)打印出發(fā)現(xiàn)的路由目標(biāo)
      4. 啟動(dòng)App的時(shí)候,開(kāi)啟debug殉疼、log(openDebug/openLog), 查看映射表是否已經(jīng)被掃描出來(lái)梯浪,形如 D/ARouter::: LogisticsCenter has already been loaded, GroupIndex[4]捌年,GroupIndex > 0
  3. 開(kāi)啟InstantRun之后無(wú)法跳轉(zhuǎn)(高版本Gradle插件下無(wú)法跳轉(zhuǎn))?

    因?yàn)殚_(kāi)啟InstantRun之后驱证,很多類文件不會(huì)放在原本的dex中延窜,需要單獨(dú)去加載,ARouter默認(rèn)不會(huì)去加載這些文件抹锄,因?yàn)榘踩蚰嫒穑挥性陂_(kāi)啟了openDebug之后 ARouter才回去加載InstantRun產(chǎn)生的文件,所以在以上的情況下伙单,需要在init之前調(diào)用openDebug

  4. TransformException:java.util.zip.ZipException: duplicate entry ....

    ARouter有按組加載的機(jī)制获高,關(guān)于分組可以參考 6-1 部分,ARouter允許一個(gè)module中存在多個(gè)分組吻育,但是不允許多個(gè)module中存在相同的分組念秧,會(huì)導(dǎo)致映射文件沖突

  5. Kotlin類中的字段無(wú)法注入如何解決?

    首先布疼,Kotlin中的字段是可以自動(dòng)注入的摊趾,但是注入代碼為了減少反射,使用的字段賦值的方式來(lái)注入的游两,Kotlin默認(rèn)會(huì)生成set/get方法砾层,并把屬性設(shè)置為private 所以只要保證Kotlin中字段可見(jiàn)性不是private即可,簡(jiǎn)單解決可以在字段上添加 @JvmField

  6. 通過(guò)URL跳轉(zhuǎn)之后贱案,在intent中拿不到參數(shù)如何解決肛炮?

    需要注意的是,如果不使用自動(dòng)注入宝踪,那么可以不寫 ARouter.getInstance().inject(this)侨糟,但是需要取值的字段仍然需要標(biāo)上 @Autowired 注解,因?yàn)?只有標(biāo)上注解之后瘩燥,ARouter才能知道以哪一種數(shù)據(jù)類型提取URL中的參數(shù)并放入Intent中秕重,這樣您才能在intent中獲取到對(duì)應(yīng)的參數(shù)

  7. 新增頁(yè)面之后,無(wú)法跳轉(zhuǎn)厉膀?

    ARouter加載Dex中的映射文件會(huì)有一定耗時(shí)悲幅,所以ARouter會(huì)緩存映射文件,直到新版本升級(jí)(版本號(hào)或者versionCode變化)站蝠,而如果是開(kāi)發(fā)版本(ARouter.openDebug())汰具, ARouter 每次啟動(dòng)都會(huì)重新加載映射文件,開(kāi)發(fā)階段一定要打開(kāi) Debug 功能

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末菱魔,一起剝皮案震驚了整個(gè)濱河市留荔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖聚蝶,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件杰妓,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡碘勉,警方通過(guò)查閱死者的電腦和手機(jī)巷挥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)验靡,“玉大人倍宾,你說(shuō)我怎么就攤上這事∈どぃ” “怎么了高职?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)辞州。 經(jīng)常有香客問(wèn)我怔锌,道長(zhǎng),這世上最難降的妖魔是什么变过? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任埃元,我火速辦了婚禮,結(jié)果婚禮上媚狰,老公的妹妹穿的比我還像新娘岛杀。我一直安慰自己,他們只是感情好哈雏,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布楞件。 她就那樣靜靜地躺著衫生,像睡著了一般裳瘪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上罪针,一...
    開(kāi)封第一講書(shū)人閱讀 52,457評(píng)論 1 311
  • 那天彭羹,我揣著相機(jī)與錄音,去河邊找鬼泪酱。 笑死派殷,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的墓阀。 我是一名探鬼主播毡惜,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼斯撮!你這毒婦竟也來(lái)了经伙?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤勿锅,失蹤者是張志新(化名)和其女友劉穎帕膜,沒(méi)想到半個(gè)月后枣氧,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡垮刹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年达吞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片荒典。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡酪劫,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出种蝶,到底是詐尸還是另有隱情契耿,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布螃征,位于F島的核電站搪桂,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏盯滚。R本人自食惡果不足惜踢械,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望魄藕。 院中可真熱鬧内列,春花似錦、人聲如沸背率。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)寝姿。三九已至交排,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間饵筑,已是汗流浹背埃篓。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留根资,地道東北人架专。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像玄帕,于是被迫代替她去往敵國(guó)和親部脚。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容