diff --git a/fml/platform/ohos/message_loop_ohos.cc b/fml/platform/ohos/message_loop_ohos.cc index c91a061a637c638707d680bdb40a796dc7c227fd..97adf76251e5ca94fa96df5d8a924ab5fdfe9815 100644 --- a/fml/platform/ohos/message_loop_ohos.cc +++ b/fml/platform/ohos/message_loop_ohos.cc @@ -66,7 +66,7 @@ void MessageLoopOhos::Run() { // |fml::MessageLoopImpl| void MessageLoopOhos::Terminate() { running_ = false; - WakeUp(fml::TimePoint::Now()); + uv_poll_stop(&poll_handle_); } // |fml::MessageLoopImpl| diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index.d.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index.d.ets index 01902264841595a7865cb4979cef7165dc8803b9..b84baab72ed69f58ed2317cd49f33655815fcfb7 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index.d.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/cpp/types/libflutter/index.d.ets @@ -86,4 +86,12 @@ export const nativeSetViewportMetrics: (nativeShellHolderId: number, devicePixel export const nativeImageDecodeCallback: (width: number, height: number, imageGeneratorPointer: number, pixelMap : image.PixelMap | null) => void; -export const nativeGetSystemLanguages: (nativeShellHolderId: number, languages: Array) => void; \ No newline at end of file +export const nativeGetSystemLanguages: (nativeShellHolderId: number, languages: Array) => void; + +/** + * Detaches flutterNapi和engine之间的关联 + * 这个方法执行前提是flutterNapi已经和engine关联 + */ +export const nativeDestroy: ( + nativeShellHolderId: number +) => void; \ No newline at end of file diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterEngine.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterEngine.ets index bd313550722bfdfdca36fb0c14eeaddae5d19fac..ed42ca6b0c308e1d84e2d84a1bca1f54e7969604 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterEngine.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterEngine.ets @@ -253,9 +253,12 @@ export default class FlutterEngine implements EngineLifecycleListener{ destroy(): void { Log.d(TAG, "Destroying."); this.engineLifecycleListeners.forEach(listener => listener.onEngineWillDestroy()) + this.pluginRegistry?.destroy(); + this.platformViewsController?.onDetachedFromNapi(); + this.dartExecutor.onDetachedFromNAPI(); this.flutterNapi.removeEngineLifecycleListener(this); this.pluginRegistry?.detachFromAbility(); - this.platformViewsController?.onDetachedFromNapi(); + this.flutterNapi.detachFromNativeAndReleaseResources(); } getRestorationChannel(): RestorationChannel | null { diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterNapi.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterNapi.ets index 11f1b234fb4acd7a734054ea0e5c4bc5f0cf9437..689d80fe4c1999272a31a35794cdce97d5dbf0d1 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterNapi.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/engine/FlutterNapi.ets @@ -100,6 +100,15 @@ export default class FlutterNapi { this.platformMessageHandler = platformMessageHandler; } + detachFromNativeAndReleaseResources(): void { + Log.i(TAG, "DetachFromNativeAndReleaseResources nativeShellHolderId=" + this.nativeShellHolderId); + this.ensureAttachedToNative(); + if (this.nativeShellHolderId) { + flutter.nativeDestroy(this.nativeShellHolderId); + this.nativeShellHolderId = null; + } + } + private ensureAttachedToNative(): void { if (this.nativeShellHolderId == null) { throw new Error( diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbility.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbility.ets index 22b808584ec6aa758fa6ab312fad4ca227b35b44..2cd5c74024cb8254f64c88b888dd1a6c4a244839 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbility.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbility.ets @@ -56,6 +56,10 @@ struct XComponentStruct { this.context = context; }) .onDestroy(() => { + let func: Function = (this.dvModelParams as Record)["xComponentDestroyCallback"]; + if (func) { + func(); + } }) } } @@ -76,6 +80,8 @@ export class FlutterAbility extends UIAbility implements Host { private mainWindow?: window.Window; private viewportMetrics = new ViewportMetrics(); private displayInfo?: display.Display; + private abilityDestroy: boolean = false; + private xComponentDestroy: boolean = false; /** * onCreate @@ -108,9 +114,15 @@ export class FlutterAbility extends UIAbility implements Host { } onDestroy() { + this.abilityDestroy = true; this.context.eventHub.off(EVENT_BACK_PRESS); if (this.stillAttachedForEvent("onDestroy")) { this?.delegate?.onDestroy(); + if (this.abilityDestroy && this.xComponentDestroy) { + Log.i(TAG, "Enter ability destroy delegate on detach"); + this.delegate?.onDetach(); + this.release(); + } } } @@ -167,12 +179,24 @@ export class FlutterAbility extends UIAbility implements Host { } } + xComponentDestroyCallback() { + this.xComponentDestroy = true; + if (this.abilityDestroy && this.xComponentDestroy) { + Log.i(TAG, "Enter xComponentDestroyCallback delegate.onDetach"); + this.delegate?.onDetach(); + this.release(); + } + } + loadContent() { if (this.windowStage != null && this.stillAttachedForEvent("loadContent")) { Log.i(TAG, 'loadContent'); let params: DVModelParameters = new DVModelParameters(); (params as Record)["xComponentId"] = this.delegate?.getFlutterNapi()?.nativeShellHolderId?.toString(); + (params as Record)["xComponentDestroyCallback"] = () => { + this.xComponentDestroyCallback(); + } let xComponentModel: DVModel = new DVModel("xComponent", params, new DVModelEvents(), new DVModelChildren(), BuildXComponentStruct); RootDvModeManager.addDvModel(xComponentModel); diff --git a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbilityDelegate.ets b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbilityDelegate.ets index cbe0e80830d86a1bb73990f10d993efef4e31a87..8d16222f7b4d4514eea64ad38a2c18cc4a15df33 100644 --- a/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbilityDelegate.ets +++ b/shell/platform/ohos/flutter_embedding/flutter/src/main/ets/embedding/ohos/FlutterAbilityDelegate.ets @@ -51,7 +51,7 @@ const FRAMEWORK_RESTORATION_BUNDLE_KEY = "framework"; class FlutterAbilityDelegate implements ExclusiveAppComponent { private host?: Host | null; flutterEngine?: FlutterEngine | null; - platformPlugin?: PlatformPlugin; + platformPlugin?: PlatformPlugin | null; private context?: common.Context; private uiContext?: UIContext | undefined; private textInputPlugin?: TextInputPlugin; @@ -255,11 +255,37 @@ class FlutterAbilityDelegate implements ExclusiveAppComponent { } onDetach() { + this.ensureAlive(); + if (this.flutterEngine) { + this.host?.cleanUpFlutterEngine(this.flutterEngine); + } + if (this.host?.shouldAttachEngineToActivity()) { // Notify plugins that they are no longer attached to an Activity. Log.d(TAG, "Detaching FlutterEngine from the Ability"); this.flutterEngine?.getAbilityControlSurface()?.detachFromAbility(); } + + if (this.platformPlugin) { + this.platformPlugin.destroy(); + this.platformPlugin = null; + } + + if (this.host?.shouldDispatchAppLifecycleState()) { + this.flutterEngine?.getLifecycleChannel()?.appIsDetached(); + } + + if (this.host?.shouldDestroyEngineWithHost()) { + this.flutterEngine?.destroy(); + + if (this.host?.getCachedEngineId()) { + FlutterEngineCache.getInstance().remove(this.host?.getCachedEngineId()); + } + + this.flutterEngine = null; + } + + this.isAttached = false; } onLowMemory(): void { diff --git a/shell/platform/ohos/ohos_shell_holder.cpp b/shell/platform/ohos/ohos_shell_holder.cpp index 26aa35c67a658f7b71eb8990de8bf48f5d5efd87..5bbb775c933d3dd6ac419462a525a38eff2e6eb7 100644 --- a/shell/platform/ohos/ohos_shell_holder.cpp +++ b/shell/platform/ohos/ohos_shell_holder.cpp @@ -209,6 +209,11 @@ OHOSShellHolder::OHOSShellHolder( is_valid_ = shell_ != nullptr; } +OHOSShellHolder::~OHOSShellHolder() { + shell_.reset(); + thread_host_.reset(); +} + bool OHOSShellHolder::IsValid() const { return is_valid_; } diff --git a/shell/platform/ohos/ohos_shell_holder.h b/shell/platform/ohos/ohos_shell_holder.h index 6e94255f2544bca19caa184ae73f8066e8ce8433..b087614432bacd10a79e16ff1f4ff5a362b41206 100644 --- a/shell/platform/ohos/ohos_shell_holder.h +++ b/shell/platform/ohos/ohos_shell_holder.h @@ -42,6 +42,8 @@ class OHOSShellHolder { std::shared_ptr napi_facade, void* plateform_loop); + ~OHOSShellHolder(); + bool IsValid() const; const flutter::Settings& GetSettings() const; diff --git a/shell/platform/ohos/platform_view_ohos.cpp b/shell/platform/ohos/platform_view_ohos.cpp index 3fc6b6b1a67a53f250101317a0b4fc7d256775d0..31ba6c5fcab56d741b6d6f374377d06766b315cc 100644 --- a/shell/platform/ohos/platform_view_ohos.cpp +++ b/shell/platform/ohos/platform_view_ohos.cpp @@ -168,6 +168,8 @@ void PlatformViewOHOS::NotifyChanged(const SkISize& size) { // |PlatformView| void PlatformViewOHOS::NotifyDestroyed() { + PlatformView::NotifyDestroyed(); + LOGI("PlatformViewOHOS NotifyDestroyed enter"); if (ohos_surface_) { fml::AutoResetWaitableEvent latch; @@ -338,6 +340,7 @@ void PlatformViewOHOS::ReleaseResourceContext() const { if (ohos_surface_) { ohos_surface_->ResourceContextClearCurrent(); } + LOGI("ReleaseResourceContext out"); } // |PlatformView|