在Bugly中发现存在偶现的崩溃问题如下:

#5404 com.alibaba.android.arouter.exception.HandlerException

更详细的信息如下:

java.lang.RuntimeException:Unable to create application com.xxx: com.alibaba.android.arouter.exception.HandlerException: ARouter::ARouter init logistics center exception! [com.alibaba.android.arouter.routes.ARouter$$Providers$$yyy]

看了ARouter所有与之相关的Issues,并没有发现解决方案。

于是查看ARouter源码,定位到如下代码,LogisticsCenter::init

    /**     * LogisticsCenter init, load all metas in memory. Demand initialization     */    public synchronized static void init(Context context, ThreadPoolExecutor tpe) throws HandlerException {        mContext = context;        executor = tpe;        try {            long startInit = System.currentTimeMillis();            //billy.qi modified at 2017-12-06            //load by plugin first            loadRouterMap();            if (registerByPlugin) {                logger.info(TAG, "Load router map by arouter-auto-register plugin.");            } else {                Set routerMap;                // It will rebuild router map every times when debuggable.                if (ARouter.debuggable() || PackageUtils.isNewVersion(context)) {                    logger.info(TAG, "Run with debug mode or new install, rebuild router map.");                    // These class was generated by arouter-compiler.                    routerMap = ClassUtils.getFileNameByPackageName(mContext, ROUTE_ROOT_PAKCAGE);                    if (!routerMap.isEmpty()) {                        context.getSharedPreferences(AROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE).edit().putStringSet(AROUTER_SP_KEY_MAP, routerMap).apply();                    }                    PackageUtils.updateVersion(context);    // Save new version name when router map update finishes.                } else {                    logger.info(TAG, "Load router map from cache.");                    routerMap = new HashSet<>(context.getSharedPreferences(AROUTER_SP_CACHE_KEY, Context.MODE_PRIVATE).getStringSet(AROUTER_SP_KEY_MAP, new HashSet()));                }                logger.info(TAG, "Find router map finished, map size = " + routerMap.size() + ", cost " + (System.currentTimeMillis() - startInit) + " ms.");                startInit = System.currentTimeMillis();                for (String className : routerMap) {                    if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_ROOT)) {                        // This one of root elements, load root.                        ((IRouteRoot) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.groupsIndex);                    } else if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_INTERCEPTORS)) {                        // Load interceptorMeta                        ((IInterceptorGroup) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.interceptorsIndex);                    } else if (className.startsWith(ROUTE_ROOT_PAKCAGE + DOT + SDK_NAME + SEPARATOR + SUFFIX_PROVIDERS)) {                        // Load providerIndex                        ((IProviderGroup) (Class.forName(className).getConstructor().newInstance())).loadInto(Warehouse.providersIndex);                    }                }            }            logger.info(TAG, "Load root element finished, cost " + (System.currentTimeMillis() - startInit) + " ms.");            if (Warehouse.groupsIndex.size() == 0) {                logger.error(TAG, "No mapping files were found, check your configuration please!");            }            if (ARouter.debuggable()) {                logger.debug(TAG, String.format(Locale.getDefault(), "LogisticsCenter has already been loaded, GroupIndex[%d], InterceptorIndex[%d], ProviderIndex[%d]", Warehouse.groupsIndex.size(), Warehouse.interceptorsIndex.size(), Warehouse.providersIndex.size()));            }        } catch (Exception e) {            throw new HandlerException(TAG + "ARouter init logistics center exception! [" + e.getMessage() + "]");        }    }

从代码可知,如果处于debuggable()或者apk的版本号变更时,ARouter会重新通过指定包名,扫描包下面包含的所有的ClassName。否则,ARouter会从缓存SharedPreferences中读取这些信息。

由于问题堆栈[com.alibaba.android.arouter.routes.ARouter$$Providers$$yyy],这里的yyy模块,我们在最近移除过,因此,考虑是因为缓存中有yyy模块,但是实际新的apk中并没有。

我们到/data/data/包名/shared_prefs/SP_AROUTER_CACHE.xml下查看,果然ROUTER_MAP中多了com.alibaba.android.arouter.routes.ARouter$$Group$$yyy这个模块。

确定了问题所在,解决就简单了:在研发和测试阶段,把ARouter.openDebug()打开,而在正式发布的版本,则不打开。

更多相关文章

  1. Android静态代码分析
  2. 【Android】附加Android源代码Androidandroid_gingerbread_javas
  3. Android中对NFC的实现代码分布在如下几个地方:
  4. Android简明开发教程二十四篇及示例代码下载
  5. Android ROM研究---如何在ubuntu下下载姜饼(Gingerbread)源代码
  6. Android最佳实践(六)之扫描二维码模块
  7. Android手机重启的核心代码
  8. Android加载对话框,异步执行代码的封装类
  9. Android 的一些比较好的开源代码项目

随机推荐

  1. 整理 酷炫 Android、Flutter 开源UI框架
  2. Android---Menu
  3. android 2D教程精华集合贴
  4. android各种广播简介
  5. 【转】每个Android开发者都应该了解的资
  6. android设置全屏以及解决设置全屏无效的
  7. android 权限配置和测试环境配置
  8. 【基于Android的ARM汇编语言系列】之六:NE
  9. Android 应用中十大常见 UX 错误
  10. ubuntu 使用adb shell命令识别android设