如何追踪CustomizedTextParser日志中规则为空错误的产生根源?
如何追踪这个CustomizedTextParser报错的根源
首先先明确下已知的关键信息:
触发报错的日志:
04-03 19:46:46.921 10152-10412/ D/CustomizedTextParser: Initialzed 04-03 19:46:46.921 10152-10412/ E/CustomizedTextParser: getCustomizedText Rule is empty. mRuleMap={} 04-03 19:46:50.921 10152-10412/ E/CustomizedTextParser: getCustomizedText Rule is empty. mRuleMap={}报错发生时正在执行:
Collections.sort(packages, new ApplicationInfo.DisplayNameComparator(mPac...
咱们一步步来拆解定位:
1. 先理清调用链路:排序逻辑怎么触发了报错方法
报错提示getCustomizedText的规则为空,而这个方法是在执行排序时触发的,那你得先搞清楚排序的比较器里是不是间接调用了CustomizedTextParser.getCustomizedText:
- 打开
ApplicationInfo.DisplayNameComparator的compare方法实现(如果是你项目里自定义的比较器直接看代码;如果是系统类,检查项目里有没有通过Hook、代理或者自定义ApplicationInfo的方式,把获取显示名称的逻辑替换成了调用CustomizedTextParser)。 - 要是找不到直接关联,就在
getCustomizedText方法里加一行日志打印调用栈:
这样就能直接看到是谁调用了这个方法,把整个调用链路理清楚。Log.e("CustomizedTextParser", "getCustomizedText called from: " + Log.getStackTraceString(new Exception()));
2. 排查CustomizedTextParser的规则加载问题
日志显示CustomizedTextParser已经初始化,但mRuleMap是空的,说明初始化和规则加载是两个独立的步骤,而且规则加载滞后了:
- 检查
CustomizedTextParser的代码:规则(比如本地配置文件、后台接口返回、数据库数据)是在初始化时同步加载的,还是异步加载的?如果是异步加载,那第一次调用getCustomizedText时,规则还没加载完成就会触发报错。 - 在规则加载完成的地方加日志,比如:
对比这个日志的时间点和报错时间点,就能确认是不是加载滞后导致的问题。Log.d("CustomizedTextParser", "Rules loaded successfully, mRuleMap size: " + mRuleMap.size());
3. 搞清楚为什么排序逻辑会被触发两次
两次报错间隔4秒,说明这段排序代码被执行了两次,你需要排查触发时机:
- 找到这段
Collections.sort所在的方法,查看它的调用场景:是页面启动时触发?还是收到广播、回调后触发?有没有可能是重复注册了监听(比如多次注册了PackageManager的监听),导致两次触发排序? - 在排序代码的前后分别加日志:
看这两行日志的输出次数和时间,和报错时间对应上,确认触发频率和时机是否符合预期。Log.d("AppSortLogic", "Starting to sort application packages"); Collections.sort(packages, new ApplicationInfo.DisplayNameComparator(mPac...)); Log.d("AppSortLogic", "Finished sorting application packages");
4. 补充边界处理,同时验证临时修复方案
如果确实是规则加载滞后的问题,可以先加临时处理避免报错,同时验证问题根源:
- 在
getCustomizedText方法里先判断mRuleMap是否为空,如果为空就返回默认的应用名称(而不是直接报错),看看排序逻辑能不能正常执行,同时观察后续规则加载完成后是否能正常工作。 - 如果是排序逻辑被重复触发,那就排查重复触发的原因,比如是否有重复的生命周期回调、重复的事件注册等。
内容的提问来源于stack exchange,提问作者Aditya Gupta
相关产品推荐
相关产品推荐

