youtube(2.10.13)在Android TV上运行的时候,概率性出现crash,crash多发生在上电开机或首次打开的时候。
--------- beginning of crash
06-02 12:13:33.335 4072 4072 E AndroidRuntime: FATAL EXCEPTION: main
06-02 12:13:33.335 4072 4072 E AndroidRuntime: Process: com.google.android.youtube.tv.recommendations, PID: 4072
06-02 12:13:33.335 4072 4072 E AndroidRuntime: java.lang.RuntimeException: Unable to create application com.google.android.apps.youtube.tv.application.TvApplication: java.lang.IllegalStateException: WorkManager is not initialized properly. You have explicitly disabled WorkManagerInitializer in your manifest, have not manually called WorkManager#initialize at this point, and your Application does not implement Configuration.Provider.
06-02 12:13:33.335 4072 4072 E AndroidRuntime: at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5384)
06-02 12:13:33.335 4072 4072 E AndroidRuntime: at android.app.ActivityThread.-wrap2(ActivityThread.java)
06-02 12:13:33.335 4072 4072 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1528)
06-02 12:13:33.335 4072 4072 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:102)
06-02 12:13:33.335 4072 4072 E AndroidRuntime: at android.os.Looper.loop(Looper.java:154)
06-02 12:13:33.335 4072 4072 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6097)
06-02 12:13:33.335 4072 4072 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
06-02 12:13:33.335 4072 4072 E AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1052)
06-02 12:13:33.335 4072 4072 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:942)
06-02 12:13:33.335 4072 4072 E AndroidRuntime: Caused by: java.lang.IllegalStateException: WorkManager is not initialized properly. You have explicitly disabled WorkManagerInitializer in your manifest, have not manually called WorkManager#initialize at this point, and your Application does not implement Configuration.Provider.
06-02 12:13:33.335 4072 4072 E AndroidRuntime: at ww.a(PG:29)
06-02 12:13:33.335 4072 4072 E AndroidRuntime: at bqz.a(PG:3)
06-02 12:13:33.335 4072 4072 E AndroidRuntime: at foc.a(PG:4)
06-02 12:13:33.335 4072 4072 E AndroidRuntime: at bqw.a(PG:17)
06-02 12:13:33.335 4072 4072 E AndroidRuntime: at cof.a(PG:20)
06-02 12:13:33.335 4072 4072 E AndroidRuntime: at cof.a(PG:18)
06-02 12:13:33.335 4072 4072 E AndroidRuntime: at com.google.android.apps.youtube.tv.application.TvApplication.onCreate(PG:32)
06-02 12:13:33.335 4072 4072 E AndroidRuntime: at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1024)
06-02 12:13:33.335 4072 4072 E AndroidRuntime: at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5381)
06-02 12:13:33.335 4072 4072 E AndroidRuntime: ... 8 more
从日志来看,可以有以下发现:
- 程序运行过程中发生了异常Exception,并且异常发生在youtube APP内部。
onCreate(PG:32)开始的行知道抛出异常的地方都在应用内部。 - 异常产生的原因是:
WorkManager没有进行合适的初始化。 - 应用内部没有捕获异常,直接进入Android默认的异常处理流程:杀死进程,并打印堆栈信息。
Youtube App是Google开发的,Android OS也是谷歌开发的,正常情况下,从哪个角度看,这个问题都应该是Google来分析解决。无奈存在一种不正常的情况,就是Android系统没有进行Google授权认证的情况下,出现的一概问题官方都不负责。这个问题也不排除是系统整合没有遵从Google的相关规定,但是这个规定有点多而且有些还很隐晦,靠猜是很难办的。
从APP开始分析
问题发生在应用内部,一般情况下都是先从应用分析。Youtube APP闭源,所以要采取一些非常规的手段,比如反编译。现在各种防止反编译的手段非常多,使用常规的工具几乎不可能,有条件的可以使用专业工具。下面是使用常规工具,反编译失败:
$ ./d2j-dex2jar.sh ../../tmp/classes.dex
dex2jar ../../tmp/classes.dex -> ./classes-dex2jar.jar
Detail Error Information in File ./classes-error.zip
Please report this file to http://code.google.com/p/dex2jar/issues/entry if possible.
系统层打补丁(下下策)
有的时候,不得不采取一些非常规的手段。比如这题APP端无法分析,可以换个角度,从crash堆栈分析,Android Framework层捕获APP抛出的异常,然后抛出一个新异常,这个新异常导致crash。所以,可以尝试把Framework抛出异常的地方进行一点小小的处理,比如针对本题的错误,不抛出异常,看APP的行为是否正常。
frameworks/base/core/java/android/app/ActivityThread.java
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
if (!mInstrumentation.onException(app, e)) {
- throw new RuntimeException(
- "Unable to create application " + app.getClass().getName()
- + ": " + e.toString(), e);
+ if(app.getClass().getName().contains("youtube") && e.toString().contains("WorkManager is not initialized")){
+ Slog.w("DSTTT", "skip youtube recommendations error!!!");
+ }
+ else {
+ throw new RuntimeException(
+ "Unable to create application " + app.getClass().getName()
+ + ": " + e.toString(), e);
+ }
}
}
} finally {
LUCKY,运行正常,用户不会体验到任何异常!
此乃非常规手段,谨慎使用!