SimpleDraweeView was not initialized异常引出的一个问题

析构潮汐
• 阅读 4585

项目最近线上开始报一个异常:SimpleDraweeView was not initialized。问题很快就定位到了,是我们使用了fresco,里面SimpleDraweeView有个静态成员:sDraweeControllerBuilderSupplier未被初始化导致:
SimpleDraweeView was not initialized异常引出的一个问题
也就是在使用SimpleDraweeView之前需要有个初始化,官方文档也有说明需要先调用下Fresco.initialize方法。

而这个初始化我们在Application的onCreate里面就调用了,为啥还会报这个错误呢?

首先怀疑类是不是被卸载了,根据这个异常的堆栈是发生在首页,也就是在Application的onCreate后进首页前类被卸载,一个类被卸载有几种情况,比如不存在该类的实例,类不存在引用等。java里面可以加启动参数来增加类卸载回调,但android里面就不太方便了。为了验证这个问题,在Application的onCreate里面引用一个SimpleDraweeView对象,发现还是崩溃了。

崩溃虽然是同一个,但也发现了更多问题,新增的引用一个SimpleDraweeView对象代码没有执行,同时发现Application的onCreate里面的debug log也没有输出,这就纳闷了,难道Application的onCreate也会不被执行?通过翻阅源码未发现attachBaseContext后面不执行onCreate的情况。

通过增加log发现onCreate执行在中间某一步被return掉了,而这个条件判断是当前进程是不是主进程的一个条件判断。

这样问题就清晰了,原来是Fresco.initialize方法虽然写在onCreate里面,但在这个机器上面onCreate执行在判断主进程的条件上面返回了,导致后面代码没有执行,大概是下面这个意思:

SimpleDraweeView was not initialized异常引出的一个问题

而getProcess实现是这样的:
SimpleDraweeView was not initialized异常引出的一个问题

相信这也是很多应用的做法,因为程序里面存在多进程,需要根据不同的进程在Application的onCreate里面做不同的事情,所以就有类似这样的代码来判断进程类型。结合上面的代码,也就是说我们判断进程的函数出现了问题,本应该是MAIN进程,却返回了是OTHER,结果导致代码提前返回。而出现这种错误的原因就是getRunningAppProcesses函数没有能够正确返回。通过增加调试日志确实发现偶尔这个函数不会返回当前程序进程。

通过反复测试,发现一些规律:在Dalvik环境下面需要做multidex,正常启动getRunningAppProcesses返回没有问题,当第一次启动dex做优化太久导致anr的时候,容易出现没有返回当前程序进程,这个问题在oppo find7 4.3系统上面很容易复现。

试着搜了下,发现还真有这种说法:

https://stackoverflow.com/que...

解决办法就是在getRunningAppProcesses判断不准的时候,增加一种方法来继续判断,该方法兼容到4.0没有问题。大概代码如下:

具体原因就不细究了,早期系统版本的问题,也不确定是不是跟厂家修改有关系。写这篇文章希望大家少走坑,多点时间陪陪家人~

欢迎关注微信公众号:安卓之美

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
4年前
javaAPI_IO流基础_异常
异常1.异常的概述和分类java中的异常有一个超类Throwable,然后其有俩个子类接口Error和Exception,其中Error是严重问题,这一个是程序中无法解决的,而另一个Exception则是一般问题。Exception又可以分为俩个:(1).编译时期异常:不是RuntimeException的异常,这一个是必须
Wesley13 Wesley13
4年前
j2Cache线上异常问题排查记录
问题背景开发反馈,线上有个服务在运行一段时间后,就会抛异常导致redis缓存不可用。项目使用了j2Caceh,异常是j2Cache的RedisCacheProvider抛出来的,如:Exceptioninthread"main"redis.clients.jedis.exceptions.JedisException:Co
Stella981 Stella981
4年前
Spring Cloud Feign 异常处理
问题最近在项目开发中,使用Feign调用服务,当触发熔断机制时,遇到了以下问题:异常信息形如:TestServiceaddRecord(ParamVO)failedandnofallbackavailable.;获取不到服务提供方抛出的原始异常信息;实现某些业务方法不进入熔断,直接往外抛出异常;
可莉 可莉
4年前
10 个深恶痛绝的 Java 异常。。
异常是Java程序中经常遇到的问题,我想每一个Java程序员都讨厌异常,一个异常就是一个BUG,就要花很多时间来定位异常问题。什么是异常及异常的分类请看这篇文章:一张图搞清楚Java异常机制(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fmp.weixin.qq
Wesley13 Wesley13
4年前
mysql too many connection 解决
  最近的项目用了动态切换数据源起初感觉还好,后来发现每次切换数据库都会创建一个新的连接,这样就导致大量的sleep线程。而mysql的默认sleep时间是28800秒。。。。默认最大连接数为151,这就导致经常会出现mysqltoomanyconnection的异常,需要重新启动项目太麻烦于是就搜了些解办法1;showvariablesli
Wesley13 Wesley13
4年前
Java入门之异常处理
1.异常概念异常指的是程序在执行过程中出现的非正常的情况,导致JVM的非正常停止。在Java中,异常是一个类,产生异常就是创建异常对象并抛出一个异常对象。异常指的并不是语法错误,语法错误,编译不会通过,而是编译通过后,程序执行异常。异常的作用是帮助我们找到程序中的问题。2.异常产生过程解析pub
Stella981 Stella981
4年前
SpringBoot过滤器中的异常处理
在昨天的文章我跟大家分享了SpringBoot中异常的处理中,我说了一个需要注意的点,就是过滤器中抛出的异常无法被异常处理类捕获,然后这个朋友就问应该如何处理。其实处理这种问题的处理方式有好几种,那么我就简单分享一下我近期一个项目中的处理方式。Filter中的异常处理思路首先我们要明白,在过滤器中我们一般是不会写很长
Easter79 Easter79
4年前
SpringBoot过滤器中的异常处理
在昨天的文章我跟大家分享了SpringBoot中异常的处理中,我说了一个需要注意的点,就是过滤器中抛出的异常无法被异常处理类捕获,然后这个朋友就问应该如何处理。其实处理这种问题的处理方式有好几种,那么我就简单分享一下我近期一个项目中的处理方式。Filter中的异常处理思路首先我们要明白,在过滤器中我们一般是不会写很长
京东云开发者|提高IT运维效率,深度解读京东云AIOps落地实践
基于深度学习对运维时序指标进行异常检测,快速发现线上业务问题时间序列的异常检测是实际应用中的一个关键问题,尤其是在IT行业。我们没有采用传统的基于阈值的方法来实现异常检测,而是通过深度学习提出了一种无阈值方法:基于LSTM网络的基线(一
如何从消失的异常堆栈定位线上问题 | 京东云技术团队
在618保障大促稳定性过程中,消失的异常堆栈可能会给我们带来严重的麻烦,因为这些堆栈信息是我们解决线上问题的关键之一。如何快速定位问题?想必大家心中都有自己的答案,当然最简单直接的办法还是查找异常堆栈信息。
京东云开发者 京东云开发者
9个月前
提高IT运维效率,深度解读京东云AIOps落地实践(异常检测篇)
作者:京东科技张静基于深度学习对运维时序指标进行异常检测,快速发现线上业务问题时间序列的异常检测是实际应用中的一个关键问题,尤其是在IT行业。我们没有采用传统的基于阈值的方法来实现异常检测,而是通过深度学习提出了一种无阈值方法:基于LSTM网络的基线(一个