Android ARouter there's no route matched错误汇总

这两天在使用ARouter时报了一个错误,于是开启ARouter的日志打印(ARouter开启日志看如下代码)看看日志,果然看到有打印“ARouter there’s no route matched”的日志。于是在网上去找解决方案,发现有很多童鞋遇到过这个问题,我也试过这些方法,最终没有解决我遇到的问题。

    private void initARouter() {
        if (BuildConfig.DEBUG) {
            // 两行开启日志代码必须写在init之前,否则这些配置在init过程中将无效
            ARouter.openLog();  // 打印日志
            ARouter.openDebug();// 开启调试模式(如果在InstantRun模式下运行,必须开启调试模式!线上版本需要关闭,否则有安全风险)
        }
        ARouter.init(this);
    }

写这篇文章是打算将“ARouter there’s no route matched”的解决方法做一个汇总,建议遇到此问题的童鞋最好看一篇关于ARouter的源码介绍,这有助于了解ARouter,对这个问题的解决有一定的帮助。这里推荐一篇文章,比较简单,点击这里

问题1:build.gradle配置不对

这是Kotlin项目的正确配置

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'

kapt {
    arguments {
        // ARouter 配置
        arg("AROUTER_MODULE_NAME", project.getName())
    }
}

android {
	// 省略......
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar']
    // 省略......
    
    // https://github.com/alibaba/ARouter/blob/master/README_CN.md
    api "com.alibaba:arouter-api:$mf_arouter_api"
    kapt "com.alibaba:arouter-compiler:$mf_arouter_compiler"

	// 省略......
}

问题2 :还是build.gradle配置不对,不过这出现在多moudle时

当我们的项目是多moudle时,如下图,这是一个多moudle的项目
Android ARouter there's no route matched错误汇总_第1张图片
除了需要像问题1中那样配置外,其他相关模块需要再次配置
kapt “com.alibaba:arouter-compiler:$mf_arouter_compiler”

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'

kapt {
    arguments {
        // ARouter 配置
        arg("AROUTER_MODULE_NAME", project.getName())
    }
}

android {
  // 省略......
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    // 省略......
    
    // core module kapt需再次依赖 -start
    kapt "com.alibaba:arouter-compiler:$mf_arouter_compiler"
    // core module kapt需再次依赖 -end
    
	// 省略......
}

问题3:不同的module使用了相同的一级路径

具体详情请看移步:
https://blog.csdn.net/qq_25412055/article/details/80651995

问题4:没有模块引入需要路由的模块

这个问题是什么意思呢,我们一般有个主模块,模块名一般叫"app",还有其他一些模块,比如模块“b”,模块“c”,模块“d”等等,其中我们有路由的模块是模块"d",如果我们在“app”模块中只依赖了模块"b"和模块“c”,如下代码所示,那么当我们在app模块或者模块“b”中通过ARouter跳转到模块“d”时就无法跳转,同时在build项目时也会打印“ARouter there’s no route matched”

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation project(":b")
    implementation project(":c")

    // 省略......
   
}

那么正确的做法是也要引入模块“d”,如下图代码所示

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation project(":b")
    implementation project(":c")
    // 也要依赖路由模块d
    implementation project(":d")

    // 省略......
   
}

问题分析,建议看到这里的童鞋最好先了解一下ARouter的源码,请看这篇
我简单贴一下ARouter中的源码,它有个工具类ClassUtils

 /**
     * 通过指定包名,扫描包下面包含的所有的ClassName
     *
     * @param context     U know
     * @param packageName 包名
     * @return 所有class的集合
     */
    public static Set<String> getFileNameByPackageName(Context context, final String packageName) throws PackageManager.NameNotFoundException, IOException, InterruptedException {
        final Set<String> classNames = new HashSet<>();

        List<String> paths = getSourcePaths(context);
        final CountDownLatch parserCtl = new CountDownLatch(paths.size());

        for (final String path : paths) {
            DefaultPoolExecutor.getInstance().execute(new Runnable() {
                @Override
                public void run() {
                    DexFile dexfile = null;

                    try {
                        if (path.endsWith(EXTRACTED_SUFFIX)) {
                            //NOT use new DexFile(path), because it will throw "permission error in /data/dalvik-cache"
                            dexfile = DexFile.loadDex(path, path + ".tmp", 0);
                        } else {
                            dexfile = new DexFile(path);
                        }

                        Enumeration<String> dexEntries = dexfile.entries();
                        while (dexEntries.hasMoreElements()) {
                            String className = dexEntries.nextElement();
                            if (className.startsWith(packageName)) {
                                classNames.add(className);
                            }
                        }
                    } catch (Throwable ignore) {
                        Log.e("ARouter", "Scan map file in dex files made error.", ignore);
                    } finally {
                        if (null != dexfile) {
                            try {
                                dexfile.close();
                            } catch (Throwable ignore) {
                            }
                        }

                        parserCtl.countDown();
                    }
                }
            });
        }

        parserCtl.await();

        Log.d(Consts.TAG, "Filter " + classNames.size() + " classes by packageName <" + packageName + ">");
        return classNames;
    }

我们重点看下代码

                        Enumeration<String> dexEntries = dexfile.entries();
                        while (dexEntries.hasMoreElements()) {
                            String className = dexEntries.nextElement();
                            if (className.startsWith(packageName)) {
                                classNames.add(className);
                            }
                        }

dexEntries有着App中所有已加载模块的类,如果我们不依赖模块“d”,那么dexEntries是没有模块"d"中的所有类的,ARouter的路由map也就不会缓存我们的路由类了,也就找不到路由类,打印“ARouter there’s no route matched”

问题5:单例类

@Route(path = ProductRouter.sProductQuickInstallDescription, name = "提供支持QuickInstall协议的设备的统一服务")
object ProductQuickInstallDescription : IProductQuickInstallDescription {

    private var context: Context? = null
    // 其他代码省略

这是Kotlin的单例类,也找不到,正确写法如下。(写的比较仓促,未深究原因)

@Route(path = ProductRouter.sProductQuickInstallDescription, name = "提供支持QuickInstall协议的设备的统一服务")
class ProductQuickInstallDescription : IProductQuickInstallDescription {

    private var context: Context? = null
    // 其他代码省略

以上是我目前能总结到原因,欢迎各位童鞋留言交流

你可能感兴趣的:(ARouter,随笔)