xugenyuan

ref |> 文章详情页Web容器复用02

Signed-off-by: xugenyuan <xugenyuan@wondertek.com.cn>
@@ -26,6 +26,7 @@ export const enum NativeCallH5Event { @@ -26,6 +26,7 @@ export const enum NativeCallH5Event {
26 export const enum NativeCallH5Type { 26 export const enum NativeCallH5Type {
27 jsCall_receiveAppData = 'jsCall_receiveAppData', 27 jsCall_receiveAppData = 'jsCall_receiveAppData',
28 jsCall_appNotifyEvent = 'jsCall_appNotifyEvent', 28 jsCall_appNotifyEvent = 'jsCall_appNotifyEvent',
  29 + jsCall_clearAppData = 'jsCall_clearAppData',
29 // TODO 业务自行新增类型,自行调用,例: 30 // TODO 业务自行新增类型,自行调用,例:
30 // TODO this.webviewControl.callHandle(NativeCallH5Type.jsCall_receiveAppData,xxxx) 31 // TODO this.webviewControl.callHandle(NativeCallH5Type.jsCall_receiveAppData,xxxx)
31 32
@@ -21,7 +21,6 @@ export struct WdWebLocalComponent { @@ -21,7 +21,6 @@ export struct WdWebLocalComponent {
21 onWebPrepared: () => void = () => { 21 onWebPrepared: () => void = () => {
22 } 22 }
23 @Prop backVisibility: boolean = false 23 @Prop backVisibility: boolean = false
24 - @Prop webResource: Resource = {} as Resource  
25 @Prop @Watch('onReloadStateChanged') reload: number = 0 24 @Prop @Watch('onReloadStateChanged') reload: number = 0
26 @State webHeight: Length = '100%' 25 @State webHeight: Length = '100%'
27 @Link isPageEnd: boolean 26 @Link isPageEnd: boolean
@@ -2,6 +2,7 @@ import { BridgeUtil, BridgeWebViewControl, Callback } from "wdJsBridge"; @@ -2,6 +2,7 @@ import { BridgeUtil, BridgeWebViewControl, Callback } from "wdJsBridge";
2 import { Message } from "wdJsBridge/src/main/ets/bean/Message"; 2 import { Message } from "wdJsBridge/src/main/ets/bean/Message";
3 import { Logger } from "wdKit"; 3 import { Logger } from "wdKit";
4 import { H5CallNativeType } from "../pages/H5CallNativeType"; 4 import { H5CallNativeType } from "../pages/H5CallNativeType";
  5 +import { NativeCallH5Type } from "../pages/NativeCallH5Type";
5 import { WebEvents } from "./WebLocalPool"; 6 import { WebEvents } from "./WebLocalPool";
6 7
7 const TAG = 'WebArticleEventHandler' 8 const TAG = 'WebArticleEventHandler'
@@ -20,8 +21,13 @@ export class WebArticleEventHandler implements WebEvents { @@ -20,8 +21,13 @@ export class WebArticleEventHandler implements WebEvents {
20 21
21 22
22 //MARK: ---- 23 //MARK: ----
23 - onPrepareForReuse(): void {  
24 - 24 + onPrepareForReuse(): boolean {
  25 + if (!this.webviewControl || this.pageLoadEnd == false) {
  26 + return false
  27 + }
  28 + this.webviewControl?.callHandle(NativeCallH5Type.jsCall_clearAppData, '', (data) => {
  29 + })
  30 + return true
25 } 31 }
26 32
27 onPageBegin(event: OnPageBeginEvent): void { 33 onPageBegin(event: OnPageBeginEvent): void {
@@ -109,7 +109,7 @@ export class WebNodeController extends NodeController { @@ -109,7 +109,7 @@ export class WebNodeController extends NodeController {
109 109
110 aboutToAppear(): void { 110 aboutToAppear(): void {
111 this.webNodeInTree = true; 111 this.webNodeInTree = true;
112 - Logger.debug(TAG, `WebNodeController aboutToAppear target: ${this.target} ==> url:${this.webOption.src}`); 112 + Logger.debug(TAG, `WebNodeController aboutToAppear target: ${this.target} ==> url:${this.webOption.src.toString()}`);
113 } 113 }
114 114
115 aboutToDisappear(): void { 115 aboutToDisappear(): void {
@@ -123,7 +123,7 @@ export class WebNodeController extends NodeController { @@ -123,7 +123,7 @@ export class WebNodeController extends NodeController {
123 // "UTF-8" 123 // "UTF-8"
124 // ); 124 // );
125 // } 125 // }
126 - Logger.debug(TAG, `WebNodeController aboutToDisappear target: ${this.target} ==> url:${this.webOption.src}`); 126 + Logger.debug(TAG, `WebNodeController aboutToDisappear target: ${this.target} ==> url:${this.webOption.src.toString()}`);
127 } catch (error) { 127 } catch (error) {
128 Logger.error(TAG,`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`); 128 Logger.error(TAG,`ErrorCode: ${(error as BusinessError).code}, Message: ${(error as BusinessError).message}`);
129 } 129 }
@@ -152,8 +152,8 @@ export class WebNodeController extends NodeController { @@ -152,8 +152,8 @@ export class WebNodeController extends NodeController {
152 new WebViewPoolData(this.webOption, this.target, this.webHeight, this.webEvents)); 152 new WebViewPoolData(this.webOption, this.target, this.webHeight, this.webEvents));
153 } 153 }
154 154
155 - prepareForReuse() {  
156 - this.webEvents?.onPrepareForReuse() 155 + prepareForReuse(): boolean | undefined {
  156 + return this.webEvents?.onPrepareForReuse()
157 } 157 }
158 158
159 destoryWeb() { 159 destoryWeb() {
@@ -189,7 +189,7 @@ export class WebNodeController extends NodeController { @@ -189,7 +189,7 @@ export class WebNodeController extends NodeController {
189 } 189 }
190 190
191 export interface WebEvents { 191 export interface WebEvents {
192 - onPrepareForReuse(): void 192 + onPrepareForReuse(): boolean
193 onPageBegin(event: OnPageBeginEvent): void; 193 onPageBegin(event: OnPageBeginEvent): void;
194 onPageEnd(event: OnPageEndEvent): void; 194 onPageEnd(event: OnPageEndEvent): void;
195 onLoadIntercept(event: OnLoadInterceptEvent): boolean; 195 onLoadIntercept(event: OnLoadInterceptEvent): boolean;
@@ -11,6 +11,8 @@ interface ArticleWebInterface { @@ -11,6 +11,8 @@ interface ArticleWebInterface {
11 webArticleEventHandler: WebArticleEventHandler 11 webArticleEventHandler: WebArticleEventHandler
12 } 12 }
13 13
  14 +const MAX_POOL_COUNT = 2
  15 +
14 export class WebPoolManager { 16 export class WebPoolManager {
15 17
16 private webTargets: string[] = [] 18 private webTargets: string[] = []
@@ -28,12 +30,12 @@ export class WebPoolManager { @@ -28,12 +30,12 @@ export class WebPoolManager {
28 createArticleWeb(param: ArticleWebInterface, taking?: boolean) : string { 30 createArticleWeb(param: ArticleWebInterface, taking?: boolean) : string {
29 let target = util.generateRandomUUID() 31 let target = util.generateRandomUUID()
30 createReuseableWeb(param.uiContext, 32 createReuseableWeb(param.uiContext,
31 - {src: param.webSrc, controller: param.webController}, 33 + {src: param.webSrc, controller: param.webController, renderMode: RenderMode.SYNC_RENDER},
32 target, 34 target,
33 800, 35 800,
34 param.webArticleEventHandler 36 param.webArticleEventHandler
35 ) 37 )
36 - if (taking != true) { 38 + if (taking != true && this.webTargets.length < MAX_POOL_COUNT) {
37 this.webTargets.push(target) 39 this.webTargets.push(target)
38 } 40 }
39 return target 41 return target
@@ -43,7 +45,15 @@ export class WebPoolManager { @@ -43,7 +45,15 @@ export class WebPoolManager {
43 // 当使用完成,需要调用recycleTarget() 45 // 当使用完成,需要调用recycleTarget()
44 takeAvaiableArticleWebTarget(param: ArticleWebInterface): string { 46 takeAvaiableArticleWebTarget(param: ArticleWebInterface): string {
45 if (this.webTargets.length) { 47 if (this.webTargets.length) {
46 - return this.webTargets.slice(0, 1).pop()! 48 + let target = this.webTargets.splice(0, 1).pop()!
  49 +
  50 + // 当pool里没有缓存,主动提前加载一个
  51 + if (this.webTargets.length == 0) {
  52 + setTimeout(() => {
  53 + this.createArticleWeb(param)
  54 + }, 500)
  55 + }
  56 + return target
47 } 57 }
48 return this.createArticleWeb(param, true) 58 return this.createArticleWeb(param, true)
49 } 59 }
@@ -59,8 +69,14 @@ export class WebPoolManager { @@ -59,8 +69,14 @@ export class WebPoolManager {
59 return 69 return
60 } 70 }
61 71
62 - nodeController.prepareForReuse()  
63 - this.webTargets.push(target) 72 + if (this.webTargets.length < MAX_POOL_COUNT) {
  73 + if (nodeController.prepareForReuse() == true) {
  74 + this.webTargets.push(target)
  75 + return
  76 + }
  77 + }
  78 +
  79 + this.destoryTarget(target)
64 } 80 }
65 81
66 // 撤底销毁 82 // 撤底销毁
@@ -111,4 +111,6 @@ export { GrayManageModel } from './src/main/ets/viewmodel/GrayManageModel' @@ -111,4 +111,6 @@ export { GrayManageModel } from './src/main/ets/viewmodel/GrayManageModel'
111 111
112 export { VoiceInputView } from './src/main/ets/components/comment/view/VoiceInputView' 112 export { VoiceInputView } from './src/main/ets/components/comment/view/VoiceInputView'
113 113
  114 +export { ComponentModule } from './src/main/ets/ComponentModule'
  115 +
114 // export {voicese} 116 // export {voicese}
  1 +import { BridgeUtil, BridgeWebViewControl } from "wdJsBridge";
  2 +import { WebArticleEventHandler, WebPoolManager } from "wdWebComponent";
  3 +
  4 +export class ComponentModule {
  5 +
  6 + static preInitArticleWebTemplate(context: UIContext) {
  7 +
  8 + let webviewControl = new BridgeWebViewControl()
  9 + WebPoolManager.sharedInstance().createArticleWeb({
  10 + uiContext: context,
  11 + webSrc: $rawfile("apph5/index.html"),
  12 + webController: webviewControl,
  13 + webArticleEventHandler: new WebArticleEventHandler(webviewControl)
  14 + })
  15 + }
  16 +}
@@ -99,20 +99,24 @@ export struct ImageAndTextWebComponent { @@ -99,20 +99,24 @@ export struct ImageAndTextWebComponent {
99 99
100 this.webPoolTargetId = WebPoolManager.sharedInstance().takeAvaiableArticleWebTarget({ 100 this.webPoolTargetId = WebPoolManager.sharedInstance().takeAvaiableArticleWebTarget({
101 uiContext: this.getUIContext(), 101 uiContext: this.getUIContext(),
102 - webSrc: $rawfile('apph5/index.html'), 102 + webSrc: $rawfile("apph5/index.html"),
103 webController: this.webviewControl, 103 webController: this.webviewControl,
104 webArticleEventHandler: new WebArticleEventHandler(this.webviewControl) 104 webArticleEventHandler: new WebArticleEventHandler(this.webviewControl)
105 }) 105 })
106 this.webviewControl = WebPoolManager.sharedInstance().getWebController(this.webPoolTargetId)! 106 this.webviewControl = WebPoolManager.sharedInstance().getWebController(this.webPoolTargetId)!
107 } 107 }
108 108
  109 + aboutToDisappear(): void {
  110 + Logger.debug(TAG, 'H5模板加载控件 aboutToDisappear');
  111 + WebPoolManager.sharedInstance().recycleTarget(this.webPoolTargetId)
  112 + }
  113 +
109 build() { 114 build() {
110 Column() { 115 Column() {
111 WdWebLocalComponent({ 116 WdWebLocalComponent({
112 webPoolTargetId: this.webPoolTargetId, 117 webPoolTargetId: this.webPoolTargetId,
113 webviewControl: this.webviewControl, 118 webviewControl: this.webviewControl,
114 reload:this.reload, 119 reload:this.reload,
115 - webResource: $rawfile('apph5/index.html'),  
116 backVisibility: false, 120 backVisibility: false,
117 onWebPrepared: this.onWebPrepared.bind(this), 121 onWebPrepared: this.onWebPrepared.bind(this),
118 isPageEnd: $isPageEnd 122 isPageEnd: $isPageEnd
1 -import { LogoutViewModel } from 'wdComponent'; 1 +import { ComponentModule, LogoutViewModel } from 'wdComponent';
2 import { GrayManageModel, mournsInfoModel } from 'wdComponent/src/main/ets/viewmodel/GrayManageModel' 2 import { GrayManageModel, mournsInfoModel } from 'wdComponent/src/main/ets/viewmodel/GrayManageModel'
3 import { BreakpointConstants, SpConstants } from 'wdConstant'; 3 import { BreakpointConstants, SpConstants } from 'wdConstant';
4 4
@@ -14,6 +14,8 @@ import { BottomNavigationComponent } from './view/BottomNavigationComponent'; @@ -14,6 +14,8 @@ import { BottomNavigationComponent } from './view/BottomNavigationComponent';
14 import LaunchDataModel from './viewModel/LaunchDataModel'; 14 import LaunchDataModel from './viewModel/LaunchDataModel';
15 import { LaunchPageModel } from './viewModel/LaunchPageModel'; 15 import { LaunchPageModel } from './viewModel/LaunchPageModel';
16 import { JSON } from '@kit.ArkTS'; 16 import { JSON } from '@kit.ArkTS';
  17 +import { WebArticleEventHandler, WebPoolManager } from 'wdWebComponent';
  18 +import { BridgeWebViewControl } from 'wdJsBridge';
17 19
18 const TAG = 'MainPage'; 20 const TAG = 'MainPage';
19 21
@@ -60,6 +62,10 @@ struct MainPage { @@ -60,6 +62,10 @@ struct MainPage {
60 } catch (e) { 62 } catch (e) {
61 Logger.error(TAG, `Unexpected Text in JSON ??` + JSON.stringify(e) +" " + dataModelStr); 63 Logger.error(TAG, `Unexpected Text in JSON ??` + JSON.stringify(e) +" " + dataModelStr);
62 } 64 }
  65 +
  66 + setTimeout(() => {
  67 + ComponentModule.preInitArticleWebTemplate(this.getUIContext())
  68 + }, 500)
63 } 69 }
64 70
65 pageTransition() { 71 pageTransition() {