mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-20 11:18:21 +00:00
Fix "The specified child already has a parent" IllegalStateException.
The problem was due to a race condition between removing a prebound widget view from the drag layer and adding the same view to the workspace upon dropping it; if you let go of the widget immediately after picking it up, the latter happened before the former. Specifically, the flow was: long-click a widget --> drop --> remove the view from the drag layer if it's not null (it is, so nothing happens) --> the view is finally bound/inflated and added to the drag layer --> add the view to the workspace --> already has a parent. There are actually 2 problems here: one is that the bind/inflate is asynchronous, and can therefore happen after dropping the widget view being inflated, and the other is that the view is added to the workspace even though the transition has barely started (we usually ignore drops if the transition is less than half complete). It turns out that this second problem was also due to a race condition, this time between dropping a widget or app onto the workspace and calling LauncherStateTransitionAnimation.dispatchOnLauncherTransitionStart(). If the drop happened before the dispatch, as in the case of the crash, then the drop was accepted because the transition progress was still 1.0 from the previous transition. I fixed the first problem by removing the drag layer widget view in Launcher where it is potentially used instead of Workspace. And I fixed the second problem by setting mTransitionProgress to 0 in Workspace.onLauncherTransitionPrepare(). I also added some debugging logs. Bug: 23896857 Change-Id: I66944e6d3f23b70dea15f7fb01af0763a1bfcbda
This commit is contained in:
@@ -2060,6 +2060,7 @@ public class Workspace extends PagedView
|
||||
@Override
|
||||
public void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace) {
|
||||
mIsSwitchingState = true;
|
||||
mTransitionProgress = 0;
|
||||
|
||||
// Invalidate here to ensure that the pages are rendered during the state change transition.
|
||||
invalidate();
|
||||
@@ -3659,11 +3660,6 @@ public class Workspace extends PagedView
|
||||
Resources res = mLauncher.getResources();
|
||||
final int duration = res.getInteger(R.integer.config_dropAnimMaxDuration) - 200;
|
||||
|
||||
// In the case where we've prebound the widget, we remove it from the DragLayer
|
||||
if (finalView instanceof AppWidgetHostView && external) {
|
||||
mLauncher.getDragLayer().removeView(finalView);
|
||||
}
|
||||
|
||||
boolean isWidget = info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET ||
|
||||
info.itemType == LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET;
|
||||
if ((animationType == ANIMATE_INTO_POSITION_AND_RESIZE || external) && finalView != null) {
|
||||
|
||||
Reference in New Issue
Block a user