出现问题版本
由于我们的项目还未升级到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);
复制代码