This repository was archived by the owner on Feb 25, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6k
Call PlatformView.dispose when removing hybrid composition platform views #21790
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,6 +14,7 @@ | |
import android.util.SparseArray; | ||
import android.view.MotionEvent; | ||
import android.view.View; | ||
import android.view.ViewGroup; | ||
import android.widget.FrameLayout; | ||
import androidx.annotation.NonNull; | ||
import androidx.annotation.Nullable; | ||
|
@@ -83,7 +84,7 @@ public class PlatformViewsController implements PlatformViewsAccessibilityDelega | |
// The views returned by `PlatformView#getView()`. | ||
// | ||
// This only applies to hybrid composition. | ||
private final SparseArray<View> platformViews; | ||
private final SparseArray<PlatformView> platformViews; | ||
|
||
// The platform view parents that are appended to `FlutterView`. | ||
// If an entry in `platformViews` doesn't have an entry in this array, the platform view isn't | ||
|
@@ -143,32 +144,24 @@ public void createAndroidViewForPlatformView( | |
} | ||
|
||
final PlatformView platformView = factory.create(context, request.viewId, createParams); | ||
final View view = platformView.getView(); | ||
if (view == null) { | ||
throw new IllegalStateException( | ||
"PlatformView#getView() returned null, but an Android view reference was expected."); | ||
} | ||
if (view.getParent() != null) { | ||
throw new IllegalStateException( | ||
"The Android view returned from PlatformView#getView() was already added to a parent view."); | ||
} | ||
platformViews.put(request.viewId, view); | ||
platformViews.put(request.viewId, platformView); | ||
} | ||
|
||
@Override | ||
public void disposeAndroidViewForPlatformView(int viewId) { | ||
// Hybrid view. | ||
final View platformView = platformViews.get(viewId); | ||
final PlatformView platformView = platformViews.get(viewId); | ||
final FlutterMutatorView parentView = platformViewParent.get(viewId); | ||
if (platformView != null) { | ||
if (parentView != null) { | ||
parentView.removeView(platformView); | ||
parentView.removeView(platformView.getView()); | ||
} | ||
platformViews.remove(viewId); | ||
platformView.dispose(); | ||
} | ||
|
||
if (parentView != null) { | ||
((FlutterView) flutterView).removeView(parentView); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should still work, no? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
((ViewGroup) parentView.getParent()).removeView(parentView); | ||
platformViewParent.remove(viewId); | ||
} | ||
} | ||
|
@@ -311,8 +304,10 @@ public void onTouch(@NonNull PlatformViewsChannel.PlatformViewTouch touch) { | |
vdControllers.get(touch.viewId).dispatchTouchEvent(event); | ||
} else if (platformViews.get(viewId) != null) { | ||
final MotionEvent event = toMotionEvent(density, touch, /*usingVirtualDiplays=*/ false); | ||
View view = platformViews.get(touch.viewId); | ||
view.dispatchTouchEvent(event); | ||
View view = platformViews.get(touch.viewId).getView(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: should it check for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
if (view != null) { | ||
view.dispatchTouchEvent(event); | ||
} | ||
} else { | ||
throw new IllegalStateException("Sending touch to an unknown view with id: " + viewId); | ||
} | ||
|
@@ -580,7 +575,7 @@ public void onPreEngineRestart() { | |
public View getPlatformViewById(Integer id) { | ||
// Hybrid composition. | ||
if (platformViews.get(id) != null) { | ||
return platformViews.get(id); | ||
return platformViews.get(id).getView(); | ||
} | ||
VirtualDisplayController controller = vdControllers.get(id); | ||
if (controller == null) { | ||
|
@@ -690,6 +685,10 @@ private void flushAllViews() { | |
controller.dispose(); | ||
} | ||
vdControllers.clear(); | ||
|
||
while (platformViews.size() > 0) { | ||
channelHandler.disposeAndroidViewForPlatformView(platformViews.keyAt(0)); | ||
} | ||
} | ||
|
||
private void initializeRootImageViewIfNeeded() { | ||
|
@@ -701,19 +700,27 @@ private void initializeRootImageViewIfNeeded() { | |
|
||
@VisibleForTesting | ||
void initializePlatformViewIfNeeded(int viewId) { | ||
final View view = platformViews.get(viewId); | ||
if (view == null) { | ||
final PlatformView platformView = platformViews.get(viewId); | ||
if (platformView == null) { | ||
throw new IllegalStateException( | ||
"Platform view hasn't been initialized from the platform view channel."); | ||
} | ||
if (platformViewParent.get(viewId) != null) { | ||
return; | ||
} | ||
if (platformView.getView() == null) { | ||
throw new IllegalStateException( | ||
"PlatformView#getView() returned null, but an Android view reference was expected."); | ||
} | ||
if (platformView.getView().getParent() != null) { | ||
throw new IllegalStateException( | ||
"The Android view returned from PlatformView#getView() was already added to a parent view."); | ||
} | ||
final FlutterMutatorView parentView = | ||
new FlutterMutatorView( | ||
context, context.getResources().getDisplayMetrics().density, androidTouchProcessor); | ||
platformViewParent.put(viewId, parentView); | ||
parentView.addView(view); | ||
parentView.addView(platformView.getView()); | ||
((FlutterView) flutterView).addView(parentView); | ||
} | ||
|
||
|
@@ -740,9 +747,11 @@ public void onDisplayPlatformView( | |
|
||
final FrameLayout.LayoutParams layoutParams = | ||
new FrameLayout.LayoutParams(viewWidth, viewHeight); | ||
final View platformView = platformViews.get(viewId); | ||
platformView.setLayoutParams(layoutParams); | ||
platformView.bringToFront(); | ||
final View view = platformViews.get(viewId).getView(); | ||
if (view != null) { | ||
view.setLayoutParams(layoutParams); | ||
view.bringToFront(); | ||
} | ||
currentFrameUsedPlatformViewIds.add(viewId); | ||
} | ||
|
||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: what about moving the checks
if (view == null)
andif(view.getParent() != null)
toinitializePlatformViewIfNeeded
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done