时间:2020/11/27
之前公司不允许csdn,笔记写在其它地方。最近整理过来
复现步骤
三大键和手势导航来回切换,进入allapps界面查看
问题原因
系统切换手势导航时,launcher多次加载导致此问题
多次加载log如下,可以发现1次系统导致的oncreate–>startloader 2次launcher自己监听广播变化导致的startloader
主要问题出在:bindworkspace结束时,executeOnNextDraw方法,此方法会设置allapps延迟加载,并在workspace下一次draw之后关闭延迟加载。
然后,startloader时,会清空clearPendingBinds,清掉关闭延迟的Runnable task列表
这样就会导致延迟加载没有得到释放,导致最后allapps显示不出来。
代码分析
AppsStore.enableDeferUpdates
AppsStore.disableDeferUpdates
// Defer updates flag used to defer all apps updates to the next draw.
public static final int DEFER_UPDATES_NEXT_DRAW = 1 << 0;
// Defer updates flag used to defer all apps updates while the user interacts with all apps.
public static final int DEFER_UPDATES_USER_INTERACTION = 1 << 1;
public void enableDeferUpdates(int flag) {
mDeferUpdatesFlags |= flag;
}
public void disableDeferUpdates(int flag) {
mDeferUpdatesFlags &= ~flag;
if (mDeferUpdatesFlags == 0 && mUpdatePending) {
notifyUpdate();
mUpdatePending = false;
}
}
如上可以看出,延迟allapps加载有2中标志位,如果多次启动同一标志位的延迟加载,flag的值不会变化,
如果2个标志位交替启动延迟加载,而少了其中1次关闭延迟加载,会导致标志位异常
正常情况 1 0 1 0 2 0 2 0
多次重启中的正常情况 1 0 1 1 0 2 0 2 0
多次重启中的异常情况1 3 1 3 1 标志异常
调用堆栈log
2020-11-27 10:35:18.433 1487-1487/com.android.launcher3 D/Launcher.Model: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbjava.lang.Throwable
at com.android.launcher3.LauncherModel.startLoader(LauncherModel.java:353)
at com.android.launcher3.LauncherModel.forceReload(LauncherModel.java:332)
at com.android.launcher3.LauncherModel.forceReload(LauncherModel.java:310)
at com.android.launcher3.LauncherAppState.onIdpChanged(LauncherAppState.java:134)
at com.android.launcher3.LauncherAppState.lambda$YEp4rTyHA6VkqbMqyth0A1jXgZA(Unknown Source:0)
at com.android.launcher3.-$$Lambda$LauncherAppState$YEp4rTyHA6VkqbMqyth0A1jXgZA.onIdpChanged(Unknown Source:2)
at com.android.launcher3.InvariantDeviceProfile.apply(InvariantDeviceProfile.java:321)
at com.android.launcher3.InvariantDeviceProfile.onConfigChanged(InvariantDeviceProfile.java:312)
at com.android.launcher3.InvariantDeviceProfile.access$1500(InvariantDeviceProfile.java:61)
at com.android.launcher3.InvariantDeviceProfile$OverlayMonitor.onReceive(InvariantDeviceProfile.java:588)
at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0$LoadedApk$ReceiverDispatcher$Args(LoadedApk.java:1550)
at android.app.-$$Lambda$LoadedApk$ReceiverDispatcher$Args$_BumDX2UKsnxLVrE6UJsJZkotuA.run(Unknown Source:2)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7386)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:980)
2020-11-27 10:35:18.468 1487-1487/com.android.launcher3 D/Launcher.Model: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbjava.lang.Throwable
at com.android.launcher3.LauncherModel.startLoader(LauncherModel.java:353)
at com.android.launcher3.Launcher.rebindModel(Launcher.java:462)
at com.android.launcher3.Launcher.onIdpChanged(Launcher.java:487)
at com.android.launcher3.Launcher.onIdpChanged(Launcher.java:470)
at com.android.launcher3.InvariantDeviceProfile.apply(InvariantDeviceProfile.java:321)
at com.android.launcher3.InvariantDeviceProfile.onConfigChanged(InvariantDeviceProfile.java:312)
at com.android.launcher3.InvariantDeviceProfile.access$1500(InvariantDeviceProfile.java:61)
at com.android.launcher3.InvariantDeviceProfile$OverlayMonitor.onReceive(InvariantDeviceProfile.java:588)
at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0$LoadedApk$ReceiverDispatcher$Args(LoadedApk.java:1550)
at android.app.-$$Lambda$LoadedApk$ReceiverDispatcher$Args$_BumDX2UKsnxLVrE6UJsJZkotuA.run(Unknown Source:2)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7386)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:980)
2020-11-27 10:35:18.717 1487-1487/com.android.launcher3 D/Launcher.Model:
2020-11-27 10:35:18.717 1487-1487/com.android.launcher3 D/Launcher.Model: bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbjava.lang.Throwable
at com.android.launcher3.LauncherModel.startLoader(LauncherModel.java:353)
at com.android.launcher3.Launcher.onCreate(Launcher.java:362)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1306)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3273)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3437)
at android.app.ActivityThread.handleRelaunchActivityInner(ActivityThread.java:5307)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:5215)
at android.app.servertransaction.ActivityRelaunchItem.execute(ActivityRelaunchItem.java:69)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ClientTransactionHandler.executeTransaction(ClientTransactionHandler.java:57)
at android.app.ActivityThread.handleRelaunchActivityLocally(ActivityThread.java:5266)
at android.app.ActivityThread.access$3500(ActivityThread.java:226)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2051)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7386)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:980)
修改方案
packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
//clearPending的时候 清除标记位,防止下次加载出现异常
public void clearPendingExecutor(ViewOnDrawExecutor executor) {
if (mPendingExecutor == executor) {
int deferFlags = mAppsView.getAppsStore().getDeferUpdatesFlags();
/* If defer updates flags contains {@link AllAppsStore#DEFER_UPDATES_NEXT_DRAW}, clear it */
if ((deferFlags & AllAppsStore.DEFER_UPDATES_NEXT_DRAW) != 0) {
mAppsView.getAppsStore().disableDeferUpdates(AllAppsStore.DEFER_UPDATES_NEXT_DRAW);
}
mPendingExecutor = null;
}
}