05-27 09:40:30.734 1381 1381 E AndroidRuntime: Caused by: kotlin.UninitializedPropertyAccessException: Recents dependencies are not initialized. Call `RecentsDependencies.maybeInitialize` before using this container.
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.recents.di.RecentsDependencies$Companion.getInstance(RecentsDependencies.kt:297)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.views.TaskView.<init>(TaskView.kt:2285)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.views.TaskView.<init>(TaskView.kt:129)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.views.TaskView.<init>(Unknown Source:17)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: ... 43 more
报错核心:
Caused by: kotlin.UninitializedPropertyAccessException: Recents dependencies are not initialized. Call `RecentsDependencies.maybeInitialize` before using this container.
明显就是调用getInstance时候抛出异常,那么到底哪里调用的getInstance呢? 就是如下代码。
packages/apps/Launcher3/quickstep/src/com/android/quickstep/recents/di/RecentsDependencies.kt
inline fun <reified T> RecentsDependencies.Companion.get(
scope: Any = "",
extras: RecentsDependenciesExtras = RecentsDependenciesExtras(),
noinline factory: ((extras: RecentsDependenciesExtras) -> T)? = null,
): T {
return getInstance().inject(scope.toScopeId(), extras, factory)
}
可以看出这里是kotlin的伴生对象(Companion Object) 和 扩展函数(Extension Function)。 总结上面定义调用方法为:
RecentsDependencies.get(context)
所以只需要找到RecentsDependencies.get(context)掉地方就是crash源头。 不过调用这个RecentsDependencies.get(context)地方比较多,具体是哪里调用的呢?
虽然地方crash可能已经通过代码找到了大概,但是其实我们还是不清楚具体哪一行代码报错的,不过可以简单打一下日志或者屏蔽等就准确定位了,这里还好调用地方就这个一点点,如果代码中很多地方都调用呢?还能用这种方法排查么。
最重要的是本身就是一个crash问题,而且系统也有完整堆栈,难道真的无法像java代码crash一样简单进行行号排查?
可以看看报错堆栈
at com.android.quickstep.views.TaskView.<init>(TaskView.kt:2285)
at com.android.quickstep.views.TaskView.<init>(TaskView.kt:129)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at
大家可能会说直接TaskView.kt:2285这一行看不就行了,可是很遗憾源码根本没有这一行。
那么也有好些同学也提出了相关方案,比如反编译等来查看,我们分别来尝试一下。
05-27 09:40:30.734 1381 1381 E AndroidRuntime: FATAL EXCEPTION: main
05-27 09:40:30.734 1381 1381 E AndroidRuntime: Process: com.android.launcher3, PID: 1381
05-27 09:40:30.734 1381 1381 E AndroidRuntime: android.view.InflateException: Binary XML file line #18 in com.android.launcher3:layout/task: Binary XML file line #18 in com.android.launcher3:layout/task: Error inflating class <unknown>
05-27 09:40:30.734 1381 1381 E AndroidRuntime: Caused by: android.view.InflateException: Binary XML file line #18 in com.android.launcher3:layout/task: Error inflating class <unknown>
05-27 09:40:30.734 1381 1381 E AndroidRuntime: Caused by: java.lang.reflect.InvocationTargetException
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at java.lang.reflect.Constructor.newInstance0(Native Method)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at android.view.LayoutInflater.createView(LayoutInflater.java:743)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:895)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:850)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at android.view.LayoutInflater.inflate(LayoutInflater.java:544)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at android.view.LayoutInflater.inflate(LayoutInflater.java:462)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.launcher3.util.ViewPool.inflateNewView(ViewPool.java:104)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.launcher3.util.ViewPool.getView(ViewPool.java:99)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.views.RecentsView.getTaskViewFromPool(RecentsView.java:2950)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.views.RecentsView.showCurrentTask(RecentsView.java:3172)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.views.RecentsView.onGestureAnimationStart(RecentsView.java:3012)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.views.LauncherRecentsView.onGestureAnimationStart(LauncherRecentsView.java:254)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.AbsSwipeUpHandler.notifyGestureAnimationStartToRecents(AbsSwipeUpHandler.java:801)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.AbsSwipeUpHandler.setupRecentsViewUi(AbsSwipeUpHandler.java:781)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.AbsSwipeUpHandler.onActivityInit(AbsSwipeUpHandler.java:656)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.AbsSwipeUpHandler$$ExternalSyntheticLambda59.test(D8$$SyntheticClass:0)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.LauncherActivityInterface.lambda$createActivityInitListener$0(LauncherActivityInterface.java:140)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.LauncherActivityInterface$$ExternalSyntheticLambda0.test(D8$$SyntheticClass:0)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.util.ContextInitListener.handleInit(ContextInitListener.java:53)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.launcher3.LauncherInitListener.handleInit(LauncherInitListener.java:36)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.launcher3.LauncherInitListener.handleInit(LauncherInitListener.java:22)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.util.ContextInitListener.init(ContextInitListener.java:49)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.launcher3.util.ContextTracker.registerCallback(ContextTracker.java:70)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.util.ContextInitListener.register(ContextInitListener.java:62)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.AbsSwipeUpHandler.initWhenReady(AbsSwipeUpHandler.java:3019)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.inputconsumers.OtherActivityInputConsumer.startTouchTrackingForWindowAnimation(OtherActivityInputConsumer.java:452)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.inputconsumers.OtherActivityInputConsumer.onMotionEvent(OtherActivityInputConsumer.java:262)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.inputconsumers.NavHandleLongPressInputConsumer.onMotionEvent(NavHandleLongPressInputConsumer.java:156)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.TouchInteractionService.onInputEvent(TouchInteractionService.java:1278)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.TouchInteractionService.$r8$lambda$JDK2db7a_ZtzI6D1EJ5hYukunXo(Unknown Source:0)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.TouchInteractionService$$ExternalSyntheticLambda6.onInputEvent(D8$$SyntheticClass:0)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.systemui.shared.system.InputChannelCompat$InputEventReceiver$1.onInputEvent(InputChannelCompat.java:78)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:277)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at android.os.MessageQueue.nativePollOnce(Native Method)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at android.os.MessageQueue.nextLegacy(MessageQueue.java:985)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at android.os.MessageQueue.next(MessageQueue.java:1094)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at android.os.Looper.loopOnce(Looper.java:197)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at android.os.Looper.loop(Looper.java:367)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:9287)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:566)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:929)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: Caused by: kotlin.UninitializedPropertyAccessException: Recents dependencies are not initialized. Call `RecentsDependencies.maybeInitialize` before using this container.
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.recents.di.RecentsDependencies$Companion.getInstance(RecentsDependencies.kt:297)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.views.TaskView.<init>(TaskView.kt:2285)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.views.TaskView.<init>(TaskView.kt:129)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: at com.android.quickstep.views.TaskView.<init>(Unknown Source:17)
05-27 09:40:30.734 1381 1381 E AndroidRuntime: ... 43 more
^C
去除优化
:~/disk_2T/ustc-aosp16/aosp16-r4/packages/apps/Launcher3$ git diff Android.bp
diff --git a/Android.bp b/Android.bp
index c71e8cf2d8..93ef5b3f3c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -628,7 +628,7 @@ android_app {
static_libs: ["Launcher3QuickStepLib"],
optimize: {
proguard_flags_files: [":launcher-proguard-rules"],
- enabled: true,
+ enabled: false,
shrink_resources: true,
},
有人提出,是不是可以使用kotlin代码转java的,是不是就可以直接定位到crash的行数了。
这里大家可以采用 android studio的Tools -> kotlin -> Show kotlin bytecode
我这边采用的是plugin的jar方式进行反编译
# ============================================
# 1. 准备三个东西:JDK 25、Fernflower、.class
# ============================================
# ① JDK 25(AS 的 Fernflower 需要 Java 21+)
JDK=/home/test/disk_2T/ustc-aosp16/aosp16-r4/prebuilts/jdk/jdk25/linux-x86/bin/java
# ② Fernflower jar(AS 自带的)
FERNFLOWER=/home/test/Downloads/android-studio-panda2-linux/android-studio/plugins/java-decompiler/lib/java-decompiler.jar
# ③ 从编译产物 JAR 中提取 TaskView.class
JAR=/home/test/disk_2T/ustc-aosp16/aosp16-r4/out/soong/.intermediates/packages/apps/Launcher3/Launcher3QuickStepLib/android_common/repackaged-jarjar/kotlinc/Launcher3QuickStepLib.jar
mkdir -p /tmp/fernflower_class
cd /tmp/fernflower_class
jar xf $JAR com/android/quickstep/views/TaskView.class
# ============================================
# 2. 运行 Fernflower 反编译
# ============================================
mkdir -p /tmp/fernflower_output
$JDK -cp $FERNFLOWER \
org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler \
/tmp/fernflower_class/com/android/quickstep/views/TaskView.class \
/tmp/fernflower_output
# ============================================
# 3. 查看反编译结果
# ============================================
ls /tmp/fernflower_output/
# → TaskView.java
gedit /tmp/fernflower_output/TaskView.java
# 构造函数中 dispatcherProvider 在第 ~399 行

使用最新的jadx 1.5.5
发现反编译后看2285行,明显也发现不对,和报错的对不上。

总结: 对于这个Launcher的报错问题,目前是没有找到一种可以直接通过看堆栈就可以直接简单定位到代码的。因为反编译器从不保留原始行号,因为它是工具class文件生成新文件,就像给你提纲和要求让你翻译文章一样会有一定差别,不是还原旧文件。
发现kotlin代码反编译成java后,根本也无法和真实的运行的kotlin程序的代码行数进行一一对应上,所以还是比较大的一个痛点问题,真的让我们java中的一个简单crash问题,排查难度和时间代价巨大,当然也有一些比如逆向的同学说这个就是小菜一碟,直接dex中.class中看就行,逆向这块就留给各位学员自己探索哈,有相关更好方法记得留言分享。
更多vip系统开发经典大厂面试题库获取,课程优惠购买成为vip学员进入vip群,积极讨论各种行业难点痛点疑难问题,答疑服务等。
请联系马哥微信:

