From b99414ecc95f8022c043977deb536b1404af82d7 Mon Sep 17 00:00:00 2001 From: aengu Date: Thu, 18 Jul 2024 12:49:53 +0800 Subject: [PATCH] disposeKeepAlive should be sure to remove the view from the previous parent and terminate process Signed-off-by: aengu --- .../plugin/webview/FlutterWebViewFactory.ets | 1 + .../plugin/webview/InAppWebViewManager.ets | 45 +++++++++++-------- .../webview/in_app_webview/FlutterWebView.ets | 7 ++- .../webview/in_app_webview/InAppWebView.ets | 4 +- .../webview/in_app_webview/OhosWebView.ets | 20 ++++++--- 5 files changed, 51 insertions(+), 26 deletions(-) diff --git a/flutter_inappwebview_ohos/ohos/src/main/ets/components/plugin/webview/FlutterWebViewFactory.ets b/flutter_inappwebview_ohos/ohos/src/main/ets/components/plugin/webview/FlutterWebViewFactory.ets index 3b48d85f..6d7ef972 100644 --- a/flutter_inappwebview_ohos/ohos/src/main/ets/components/plugin/webview/FlutterWebViewFactory.ets +++ b/flutter_inappwebview_ohos/ohos/src/main/ets/components/plugin/webview/FlutterWebViewFactory.ets @@ -73,6 +73,7 @@ export default class FlutterWebViewFactory extends PlatformViewFactory { viewId = keepAliveId; } flutterWebView = new FlutterWebView(this.plugin, context, viewId, params); + flutterWebView.platformViewId = id; } if (shouldMakeInitialLoad) { diff --git a/flutter_inappwebview_ohos/ohos/src/main/ets/components/plugin/webview/InAppWebViewManager.ets b/flutter_inappwebview_ohos/ohos/src/main/ets/components/plugin/webview/InAppWebViewManager.ets index 4a220839..fb3e1759 100644 --- a/flutter_inappwebview_ohos/ohos/src/main/ets/components/plugin/webview/InAppWebViewManager.ets +++ b/flutter_inappwebview_ohos/ohos/src/main/ets/components/plugin/webview/InAppWebViewManager.ets @@ -13,16 +13,20 @@ * limitations under the License. */ -import { MethodCall, MethodChannel } from '@ohos/flutter_ohos'; +import { + FlutterAbility, + FlutterEngine, FlutterEngineCache, FlutterManager, MethodCall, MethodChannel } from '@ohos/flutter_ohos'; import { MethodResult } from '@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel'; import { Params } from '@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView' import { DVModel, DVModelParameters } from '@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicView'; import InAppWebViewFlutterPlugin from '../InAppWebViewFlutterPlugin'; import ChannelDelegateImpl from '../types/ChannelDelegateImpl'; import { FlutterWebView } from './in_app_webview/FlutterWebView'; -import { Context } from '@kit.AbilityKit'; +import { common, Context } from '@kit.AbilityKit'; import web_webview from '@ohos.web.webview'; import business_error from '@ohos.base'; +import EventConstant from '../EventConstant' +import JavaScriptBridgeJS from '../plugin_scripts_js/JavaScriptBridgeJS'; const LOG_TAG = "InAppWebViewManager" const METHOD_CHANNEL_NAME = "com.pichillilorenzo/flutter_inappwebview_manager" @@ -145,26 +149,29 @@ export class InAppWebViewManager extends ChannelDelegateImpl { public disposeKeepAlive(keepAliveId: string): void { let flutterWebView: FlutterWebView | undefined = this.keepAliveWebViews.get(keepAliveId) if (flutterWebView != null) { - flutterWebView.keepAliveId = null; - // be sure to remove the view from the previous parent. - let view: WrappedBuilder<[Params]> = flutterWebView.getView(); - if (view != null) { - // let parent: ViewGroup = view.getParent(); - // if (parent != null) { - // parent.removeView(view); - // } + this.keepAliveWebViews.delete(keepAliveId) + + // NOTE: 热重启后,释放掉运行中的webview + let curFlutterAbility = FlutterManager.getInstance().getUIAbility(); + if( curFlutterAbility instanceof FlutterAbility ) { + let flutterView = curFlutterAbility.getFlutterView(); + let flutterWebViewOrNot = flutterView?.getPlatformView(); + if( flutterWebViewOrNot instanceof FlutterWebView ) { + if( flutterWebViewOrNot.keepAliveId == keepAliveId ) { + curFlutterAbility.getFlutterEngine()?.getPlatformViewsController()?.dispose(flutterWebViewOrNot?.platformViewId); // 释放掉热重启前的DynamicView -> FlutterView -> PlatformView + // let context = getContext() as common.UIAbilityContext; + + flutterWebViewOrNot!.getWebView()!.ohosWebview?.dispose(); + + flutterWebViewOrNot.getController().deleteJavaScriptRegister(JavaScriptBridgeJS.JAVASCRIPT_BRIDGE_NAME); + flutterWebViewOrNot.getController().terminateRenderProcess(); + } + } } + + flutterWebView.keepAliveId = null; flutterWebView.dispose(); } - let containsKey: boolean = true - for(let key of this.keepAliveWebViews.keys()) { - if(key == keepAliveId) { - containsKey = false - } - } - if (containsKey) { - this.keepAliveWebViews.set(keepAliveId, undefined); - } } public clearAllCache(context: Context, includeDiskFiles: boolean): void { diff --git a/flutter_inappwebview_ohos/ohos/src/main/ets/components/plugin/webview/in_app_webview/FlutterWebView.ets b/flutter_inappwebview_ohos/ohos/src/main/ets/components/plugin/webview/in_app_webview/FlutterWebView.ets index c745bd5b..cb66bed6 100644 --- a/flutter_inappwebview_ohos/ohos/src/main/ets/components/plugin/webview/in_app_webview/FlutterWebView.ets +++ b/flutter_inappwebview_ohos/ohos/src/main/ets/components/plugin/webview/in_app_webview/FlutterWebView.ets @@ -26,6 +26,7 @@ import PullToRefreshLayout from '../../pull_to_refresh/PullToRefreshLayout'; import { DisplayListenerProxy } from './DisplayListenerProxy'; import PullToRefreshSettings from '../../pull_to_refresh/PullToRefreshSettings'; import { FindInteractionController } from '../../find_interaction/FindInteractionController'; +import web_webview from '@ohos.web.webview' const LOG_TAG: string = "IAWFlutterWebView"; @@ -33,6 +34,7 @@ export class FlutterWebView extends PlatformWebView { private webView: InAppWebView | null; public pullToRefreshLayout: PullToRefreshLayout | null = null; public keepAliveId: string | null = null + public platformViewId: number | null = null constructor(plugin: InAppWebViewFlutterPlugin, context: Context, id: number, params: Map) { super(); @@ -62,6 +64,9 @@ export class FlutterWebView extends PlatformWebView { } this.webView = new InAppWebView(context, plugin, id, windowId, customSettings, userScripts, contextMenu) + if( this.keepAliveId != null ) { + plugin.inAppWebViewManager?.keepAliveWebViews.set(this.keepAliveId, this) + } displayListenerProxy.onPostWebViewInitialization(); //displayListenerProxy.onPostWebViewInitialization(displayManager); // set MATCH_PARENT layout params to the WebView, otherwise it won't take all the available space! @@ -137,7 +142,7 @@ export class FlutterWebView extends PlatformWebView { } dispose(): void { - if (this.keepAliveId != null && this.webView != null) { + if (this.keepAliveId == null && this.webView != null) { this.webView.dispose(); this.webView = null; diff --git a/flutter_inappwebview_ohos/ohos/src/main/ets/components/plugin/webview/in_app_webview/InAppWebView.ets b/flutter_inappwebview_ohos/ohos/src/main/ets/components/plugin/webview/in_app_webview/InAppWebView.ets index 38401886..d77ff595 100644 --- a/flutter_inappwebview_ohos/ohos/src/main/ets/components/plugin/webview/in_app_webview/InAppWebView.ets +++ b/flutter_inappwebview_ohos/ohos/src/main/ets/components/plugin/webview/in_app_webview/InAppWebView.ets @@ -63,7 +63,8 @@ import animator, { AnimatorOptions, AnimatorResult } from '@ohos.animator'; import common from '@ohos.app.ability.common'; import { FindInteractionController } from '../../find_interaction/FindInteractionController'; import PullToRefreshLayout from '../../pull_to_refresh/PullToRefreshLayout'; -import EventConstant from '../../EventConstant' +import EventConstant from '../../EventConstant'; +import { OhosWebView } from './OhosWebView'; const TAG = "InAppWebView" const METHOD_CHANNEL_NAME_PREFIX = "com.pichillilorenzo/flutter_inappwebview_"; @@ -110,6 +111,7 @@ export default class InAppWebView implements InAppWebViewInterface { private viewWidth = 0; private viewHeight= 0; private curUrl: string | Resource = ""; + public ohosWebview: OhosWebView | null = null; constructor(context: Context, plugin: InAppWebViewFlutterPlugin, id: number, windowId: number | null | undefined, customSettings: InAppWebViewSettings, userScripts: Array, contextMenu?: Map) { diff --git a/flutter_inappwebview_ohos/ohos/src/main/ets/components/plugin/webview/in_app_webview/OhosWebView.ets b/flutter_inappwebview_ohos/ohos/src/main/ets/components/plugin/webview/in_app_webview/OhosWebView.ets index 449b13b1..d799045f 100644 --- a/flutter_inappwebview_ohos/ohos/src/main/ets/components/plugin/webview/in_app_webview/OhosWebView.ets +++ b/flutter_inappwebview_ohos/ohos/src/main/ets/components/plugin/webview/in_app_webview/OhosWebView.ets @@ -31,29 +31,39 @@ export struct OhosWebView { @State isEnableRefresh: boolean = false @State startScripts: Array = []; @State cacheEnabled: boolean = true + private pullSetRefreshingCallback: Function | null = null; + private updateStartScriptsCallback: Function | null = null; + private updateCacheEnableCallback: Function | null = null; aboutToAppear(): void { + this.inAppWebView!.ohosWebview = this; this.isEnableRefresh = this.inAppWebView!.getPullToRefreshLayout().settings.enabled; this.cacheEnabled = this.inAppWebView!.customSettings.cacheEnabled; this.startScripts = this.inAppWebView!.userContentController.getStartScripts() let context = getContext() as common.UIAbilityContext; - context.eventHub.on(EventConstant.EVENT_PULL_SETREFRESHING, (refreshing : boolean) => { + context.eventHub.on(EventConstant.EVENT_PULL_SETREFRESHING, this.pullSetRefreshingCallback = (refreshing : boolean) => { this.isRefreshing = refreshing; }); - context.eventHub.on(EventConstant.EVENT_UPDATE_STARTSCRIPTS, (scripts : Array) => { + context.eventHub.on(EventConstant.EVENT_UPDATE_STARTSCRIPTS, this.updateStartScriptsCallback = (scripts : Array) => { this.startScripts = scripts; }); - context.eventHub.on(EventConstant.EVENT_UPDATE_CACHEENABLE, (enable : boolean) => { + context.eventHub.on(EventConstant.EVENT_UPDATE_CACHEENABLE, this.updateCacheEnableCallback = (enable : boolean) => { this.cacheEnabled = enable; }); } aboutToDisappear(): void { + this.dispose(); + } + + dispose(): void { let context = getContext() as common.UIAbilityContext; - context.eventHub.off(EventConstant.EVENT_PULL_SETREFRESHING); - context.eventHub.off(EventConstant.EVENT_UPDATE_STARTSCRIPTS); + context.eventHub.off(EventConstant.EVENT_PULL_SETREFRESHING, this.pullSetRefreshingCallback); + context.eventHub.off(EventConstant.EVENT_UPDATE_STARTSCRIPTS, this.updateStartScriptsCallback); + context.eventHub.off(EventConstant.EVENT_UPDATE_CACHEENABLE, this.updateCacheEnableCallback); + this.inAppWebView!.ohosWebview = null; } build() { -- Gitee