出现问题版本

由于我们的项目还未升级到androidx,所以Lottie库的版本我使用的是2.7.0

implementation 'com.airbnb.android:lottie:2.7.0'

近期的需求是使用Lottie写一个有动效切换的底部Tab,在版本发布后,线上出现了如下的crash信息:

java.lang.IllegalStateException: Unable to parse composition
	at com.airbnb.lottie.LottieAnimationView$2.a(LottieAnimationView.java:68)
	at com.airbnb.lottie.LottieAnimationView$2.a(LottieAnimationView.java:66)
	at com.airbnb.lottie.l.a(LottieTask.java:167)
	at com.airbnb.lottie.l.a(LottieTask.java:26)
	at com.airbnb.lottie.l$1.run(LottieTask.java:142)
	at android.os.Handler.handleCallback(Handler.java:790)
	at android.os.Handler.dispatchMessage(Handler.java:99)
	at android.os.Looper.loop(Looper.java:192)
	at android.app.ActivityThread.main(ActivityThread.java:6770)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:556)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:875)
Caused by: java.util.concurrent.ExecutionException: java.lang.AssertionError
	at java.util.concurrent.FutureTask.report(FutureTask.java:123)
	at java.util.concurrent.FutureTask.get(FutureTask.java:193)
	at com.airbnb.lottie.l$2.run(LottieTask.java:189)
Caused by: java.lang.AssertionError
	at android.util.JsonReader.peek(JsonReader.java:363)
	at android.util.JsonReader.expect(JsonReader.java:308)
	at android.util.JsonReader.beginObject(JsonReader.java:293)
	at com.airbnb.lottie.parser.t.a(LottieCompositionParser.java:42)
	at com.airbnb.lottie.e.b(LottieCompositionFactory.java:229)
	at com.airbnb.lottie.e$4.a(LottieCompositionFactory.java:218)
	at com.airbnb.lottie.e$4.call(LottieCompositionFactory.java:216)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
	at java.lang.Thread.run(Thread.java:764)

Lottie tab思路是这样的,用户首次进入App时还使用之前的静态资源做tab图标,并向服务器拉取相关json文件并保存至本地,下次用户再次进入App时再使用Lottie去加载这些json文件,所以我使用Lottie的 setAnimationFromJson(json,key) 去加载。

lottieAnimationView.setAnimationFromJson(tabs.json,tabs.title);

本来测试都没有问题,可是线上Android8.x、Android7的部分机型会出现crash,报错信息如上问题描述所示。

一开始是想着,我使用try-catch去包裹该方法就可以使程序不崩溃,可是发布后发现该问题还是未解决。

try{
      lottieAnimationView.setAnimationFromJson(tabs.json,tabs.title);
}catch(Exception e){

查看该方法的内部实现发现,它使用了线程去异步加载json文件,子线程中抛出的异常在主线程中无法直接使用try-cache捕获。

tabs.json 为服务器拉取并保存在本地的json串,tabs.title为tab的标题,这里作为Lottie的key

lottieAnimationView.setAnimationFromJson(tabs.json,tabs.title);
   LottieCompositionFactory.fromJsonString(tabs.json, tabs.title)
                                        .addFailureListener(new LottieListener<Throwable>() {
                                            @Override
                                            public void onResult(Throwable result) {
                                                //如果网络的lottie json格式解析错误则配置本地的资源
                                                setDefaultLottieView();
                                        .addListener(new LottieListener<LottieComposition>() {
                                            @Override
                                            public void onResult(LottieComposition result) {
                                                lottieAnimationView.setComposition(result);
复制代码
分类:
Android
标签: