上图是线上集成Facebook的Fresco图片框架而导致的一个异常,bugly异常统计历史累计1409次。
在Fresco的gitHub上issue的提问比比皆是,但有效的解决方案却是少之又少,基本上都是不靠谱的,Fresco官方甚至每次回答这个问题时都是新版本已解决等等,但是问题依旧。
跟同事讨论提到,可以尝试通过分析源码捕获这个崩溃异常再做操作,即使so文件找不到图片不显示也行,不要让应用崩溃!
按照这个思路下载了Fresco的源码,准备啃一口它的源码了,当然我肯定想要以最小的代价解决这个问题,所以百度大法搞起,瞧一瞧看有没有人解决这个问题,很遗憾百度上找出来的也是没啥用,那只能祭出绝招Google大法了。
在Google搜索中找到了这么一条信息,跳过发现还是Fresco的github上issue,本来都打算退出了,但瞄了瞄,这一瞄找到了解决办法。
这位大佬说他有一个解决方案,并且给出了代码(虽然是Kotlin写的,但是我会告诉你我学过kotlin?)而且还点出了造成这个错误的原因是libimagepipeline.so文件,如果我们捕获到这个异常并尝试处理它就能解决这个问题,这和讨论的思路相同了,而且看到下面的点赞量,我立马想试试了。
代码量很少总共就这么多,核心的其实就几行,添加后打包测试,通过云测提供的云真机,对修改后的方案进行验证,效果很好,出现崩溃的机子在安装新包后运行正常且图片正常加载,效果棒棒哒!
解决了问题,我们来研究一下导致整个问题的根本原因是什么,不能只拿结果不管过程。
根据异常分析报错的原因是so库加载失败,CPU架构找不到对应的so文件,通过bugly异常分析中看到:so文件加载失败后,Fresco调用了libimagepipeline.so文件下的SoLoader native方法,这个时候问题就来了,so文件已经加载失败了,它怎么去找内部的方法呢?自然就报错了。
而上面通过简单的几行代码就解决了这个问题,是怎么做到呢?这几行代码的作用是什么呢!我们来分析一下。
1.ImagePipelineNativeLoader.load();
这个方法我们从名字都能看出来是native方法初始化,进入方法里面
public class ImagePipelineNativeLoader {
public static final String DSO_NAME = "imagepipeline";
public static final List<String> DEPENDENCIES;
static {
List<String> dependencies = new ArrayList<String>();
DEPENDENCIES = Collections.unmodifiableList(dependencies);
}
public static void load() {
SoLoader.loadLibrary("imagepipeline");
}
}
我们可以看到它就是加载so文件中的方法,新的解决方案是把它放到初始化时调用,如果此时so文件加载失败就会报