From 0614d0b48aedcb33be21d910d21f531f0988bd82 Mon Sep 17 00:00:00 2001 From: caizhixing Date: Mon, 9 Nov 2026 01:58:58 -0800 Subject: [PATCH] fix : NPE in Workspace.onDrop when the dropped cell is detached from the workspace (#7457) Co-authored-by: caizhixing <17589399+caizhixing03@user.noreply.gitee.com> --- src/com/android/launcher3/Workspace.java | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 816ea455d8..1c018b979b 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -2398,8 +2398,13 @@ public class Workspace extends PagedView CellLayoutLayoutParams lp = (CellLayoutLayoutParams) cell.getLayoutParams(); mTargetCell[0] = lp.getCellX(); mTargetCell[1] = lp.getCellY(); - CellLayout layout = (CellLayout) cell.getParent().getParent(); - layout.markCellsAsOccupiedForView(cell); + // The cell can be detached from the workspace while the drag is in + // progress (e.g. if the workspace rebound mid-drag); there is no + // parent layout left to mark as occupied in that case. + CellLayout layout = getParentCellLayoutForView(cell); + if (layout != null) { + layout.markCellsAsOccupiedForView(cell); + } } } else { // When drag is cancelled, reattach content view back to its original parent. @@ -2416,7 +2421,19 @@ public class Workspace extends PagedView } } - final CellLayout parent = (CellLayout) cell.getParent().getParent(); + // The dropped cell can be detached from the workspace at this point, e.g. a + // widget whose host view failed to re-attach in addInScreen after being + // detached from the drag view, or a view removed by a mid-drag rebind. + // Skip the drop animations and clean up the drag view instead of crashing. + final CellLayout parent = getParentCellLayoutForView(cell); + if (parent == null) { + d.deferDragViewCleanupPostAnimation = false; + cell.setVisibility(VISIBLE); + if (!mLauncher.isInState(EDIT_MODE)) { + mLauncher.getStateManager().goToState(NORMAL, SPRING_LOADED_EXIT_DELAY); + } + return; + } if (d.dragView.hasDrawn()) { if (droppedOnOriginalCellDuringTransition) { // Animate the item to its original position, while simultaneously exiting