mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Delay platform view removal to submitFrame. (#8380)
Remove platform views inside OnDispose might cause issue if it happens before SubmitFrame and the active_composition_order has not been updated. We will be left at a situation where the active_composition_order still contains the old view, but the view is actually removed from the UIView hierarchy. We now cache the views need to be removed in OnDispose and actually remove them in SubmitFrame. At the same time, we remove stop detaching the subviews if they were disposed. As a side effect, this update will also fix flutter/flutter#30220
This commit is contained in:
parent
c991647404
commit
cfe8675ff5
@ -100,12 +100,8 @@ void FlutterPlatformViewsController::OnDispose(FlutterMethodCall* call, FlutterR
|
||||
details:[NSString stringWithFormat:@"view id: '%lld'", viewId]]);
|
||||
return;
|
||||
}
|
||||
|
||||
UIView* touch_interceptor = touch_interceptors_[viewId].get();
|
||||
[touch_interceptor removeFromSuperview];
|
||||
views_.erase(viewId);
|
||||
touch_interceptors_.erase(viewId);
|
||||
overlays_.erase(viewId);
|
||||
// We wait for next submitFrame to dispose views.
|
||||
views_to_dispose_.insert(viewId);
|
||||
result(nil);
|
||||
}
|
||||
|
||||
@ -213,6 +209,8 @@ void FlutterPlatformViewsController::Reset() {
|
||||
bool FlutterPlatformViewsController::SubmitFrame(bool gl_rendering,
|
||||
GrContext* gr_context,
|
||||
std::shared_ptr<IOSGLContext> gl_context) {
|
||||
DisposeViews();
|
||||
|
||||
bool did_submit = true;
|
||||
for (size_t i = 0; i < composition_order_.size(); i++) {
|
||||
int64_t view_id = composition_order_[i];
|
||||
@ -265,12 +263,30 @@ void FlutterPlatformViewsController::DetachUnusedLayers() {
|
||||
|
||||
for (int64_t view_id : active_composition_order_) {
|
||||
if (composition_order_set.find(view_id) == composition_order_set.end()) {
|
||||
if (touch_interceptors_.find(view_id) == touch_interceptors_.end()) {
|
||||
continue;
|
||||
}
|
||||
[touch_interceptors_[view_id].get() removeFromSuperview];
|
||||
[overlays_[view_id]->overlay_view.get() removeFromSuperview];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FlutterPlatformViewsController::DisposeViews() {
|
||||
if (views_to_dispose_.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int64_t viewId : views_to_dispose_) {
|
||||
UIView* touch_interceptor = touch_interceptors_[viewId].get();
|
||||
[touch_interceptor removeFromSuperview];
|
||||
views_.erase(viewId);
|
||||
touch_interceptors_.erase(viewId);
|
||||
overlays_.erase(viewId);
|
||||
}
|
||||
views_to_dispose_.clear();
|
||||
}
|
||||
|
||||
void FlutterPlatformViewsController::EnsureOverlayInitialized(int64_t overlay_id) {
|
||||
if (overlays_.count(overlay_id) != 0) {
|
||||
return;
|
||||
|
||||
@ -91,6 +91,10 @@ class FlutterPlatformViewsController {
|
||||
GrContext* overlays_gr_context_;
|
||||
SkISize frame_size_;
|
||||
|
||||
// Method channel `OnDispose` calls adds the views to be disposed to this set to be disposed on
|
||||
// the next frame.
|
||||
std::unordered_set<int64_t> views_to_dispose_;
|
||||
|
||||
// A vector of embedded view IDs according to their composition order.
|
||||
// The last ID in this vector belond to the that is composited on top of all others.
|
||||
std::vector<int64_t> composition_order_;
|
||||
@ -106,6 +110,8 @@ class FlutterPlatformViewsController {
|
||||
void OnRejectGesture(FlutterMethodCall* call, FlutterResult& result);
|
||||
|
||||
void DetachUnusedLayers();
|
||||
// Dispose the views in `views_to_dispose_`.
|
||||
void DisposeViews();
|
||||
void EnsureOverlayInitialized(int64_t overlay_id);
|
||||
void EnsureGLOverlayInitialized(int64_t overlay_id,
|
||||
std::shared_ptr<IOSGLContext> gl_context,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user