Flutter-用webview_flutter中封装JSBridge

最近的业务需要使用Flutter开发App应用,其中打算将部分已有的Web应用进行复用,因此需要研究一下Flutter的Hybird应用开发,对JSBridge的简单封装,最终react中调用效果如下:

AppSDK.Test({
  text: 'Test!!',
  onSuccess: (e) => {
    setTest((state) => e.text);
  },
  onFail: (e) => {
   console.log('inFail',e);
  },
});

需满足以下条件:

  • 方法调用方式类似于wx的写法
  • 实现双向通信
  • 可以传入回调函数,this指向定义它的上下文对象

1. flutter项目配置文件pubspec.yaml中引入依赖:

dependencies:  
   webview_flutter: ^4.2.2

2. flutter中使用

main.dart

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_flutter_android/webview_flutter_android.dart';
import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';

void main() => runApp(MaterialApp(
      title: '',
      home: WebViewExample(),
    ));

class WebViewExample extends StatefulWidget {
  const WebViewExample({super.key});

  
  State<WebViewExample> createState() => _WebViewExampleState();
}

class _WebViewExampleState extends State<WebViewExample> {
  late final WebViewController _controller;
  
  void initState() {
    super.initState();
    late final PlatformWebViewControllerCreationParams params;
    if (WebViewPlatform.instance is WebKitWebViewPlatform) {
      params = WebKitWebViewControllerCreationParams(
        allowsInlineMediaPlayback: true,
        mediaTypesRequiringUserAction: const <PlaybackMediaTypes>{},
      );
    } else {
      params = const PlatformWebViewControllerCreationParams();
    }

    final WebViewController controller =
        WebViewController.fromPlatformCreationParams(params);

    controller
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setBackgroundColor(const Color(0x00000000))
      ..loadRequest(Uri.parse('https://www.baidu.com/'));

    // #docregion platform_features
    if (controller.platform is AndroidWebViewController) {
      AndroidWebViewController.enableDebugging(true);
      (controller.platform as AndroidWebViewController)
          .setMediaPlaybackRequiresUserGesture(false);
    }
    _controller = controller;
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body:WebViewWidget(controller: _controller)
    );
  }
}

3. JSBridge封装

3.1 webview发送消息给Native

let callbackId = 1;
function callAppMethod(config) {
  // 注册全局回调函数
  const callbackName = `${config.method}_${callbackId}`;
  const params = config.params;
  for (let key in params) {
    if (typeof params[key] === 'function') {
      params[key].bind(config);
    }
  }
  window[callbackName] = params;
  //向Native发送消息
  AppSDK.postMessage(
    JSON.stringify({ ...config, callbackName }),
  );
}
export const Test = (params) => {
  callAppMethod({
    method: 'Test',
    params,
  });
};

3.2 Native接收webview发送的消息

main.dart

import 'app_sdk/web_call_app.dart';

...

    controller
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..setBackgroundColor(const Color(0x00000000))
      // 
      ..addJavaScriptChannel(
        'AppSDK',
        onMessageReceived: (JavaScriptMessage message) async {
          Map messageData = jsonDecode(message.message);
          //处理接收到的参数
            handerWebMessage(messageData, _controller);
        },
      )

web_call_app.dart

import 'dart:convert';

import 'package:answer/app_sdk/gromore_sdk.dart';
import 'package:flutter/cupertino.dart';

import 'app_sdk.dart';

void handerWebMessage(message, controller) {
  debugPrint('handerWebMessage接收到的message: $message');
  String method = message['method'];
  String callbackName = message['callbackName'];
  Map params = new Map();
  if (message['params'] is Map) {
    params.addAll(message['params']);
  }
  // 所有的API均通过handlers进行映射,键值对应前端传入的method
  Map handlers = getHandlers();
  if (handlers.containsKey(method)) {
    try {
      handlers[method](
          params: params,
          runJSFunction: (String fn, [e = '']) {
          //执行webview定义的回调函数
            controller.runJavaScript('''
                window.$callbackName.$fn(${jsonEncode(e)})
                delete window[$callbackName]
                ''');
          });
    } catch (e) {
      debugPrint('$method:$e');
    }
  } else {
    debugPrint('无$method对应接口实现');
  }
}

Map getHandlers() {
  return {
    'Test': ({params, runJSFunction}) {
      debugPrint('-----Test-------');
      runJSFunction('onSuccess', {
        'type': 'success', 
        'text': params['text']
      });
    }
  };
}

<think>好的,我现在需要回答用户关于Flutter WebView和ArkTS WebView在渲染3D网页性能对比的问题。首先,我需要明确这两个技术的基本情况。 FlutterWebView使用的是webview_flutter插件,基于原生WebView组件,比如AndroidWebView和iOS的WKWebView。根据引用[3],Flutter WebView在加载HTML时性能关键,特别是渲染本地图表的情况。而ArkTS是鸿蒙系统的开发语言,ArkTS WebView应该是鸿蒙系统的原生组件,可能优化更好,因为深度集成系统。 接下来,性能对比需要考虑几个方面:渲染引擎、硬件加速、内存管理、JavaScript执行效率、3D API支持。Flutter WebView依赖原生WebView,所以不同平台上可能表现不同。例如,iOS的WKWebView性能较好,而AndroidWebView因版本不同差异大。ArkTS WebView作为鸿蒙原生,可能在渲染和资源调度上更高效,尤其是针对鸿蒙设备优化过。 3D网页通常使用WebGL或Three.js,所以WebView对WebGL的支持和GPU加速很重要。引用[3]提到Flutter WebView加载本地资源优化性能,但3D渲染需要更多GPU资源,可能受限于Flutter的插件桥接层。ArkTS WebView如果直接调用系统GPU资源,可能更流畅。 内存管理方面,Flutter通过Dart与原生通信可能有开销,而ArkTS作为系统级语言,内存管理更高效,减少卡顿。引用[4]指出Flutter需要处理适配和动态刷新,可能影响性能。ArkTS可能在这方面更自动化。 兼容性方面,Flutter跨平台,但不同系统WebView表现不一。ArkTS专为鸿蒙优化,可能在鸿蒙设备上更稳定,但跨平台能力有限。 总结,ArkTS WebView在鸿蒙设备上可能性能更好,但Flutter的跨平台优势明显。需要建议用户根据目标平台选择,并参考实际测试数据。</think>### Flutter WebView 与 ArkTS WebView 渲染 3D 网页性能对比分析 #### 1. **技术基础差异** - **Flutter WebView**:基于 `webview_flutter` 插件,本质是对原生 WebView封装(如 AndroidWebView 或 iOS 的 WKWebView)[^2][^3]。 - **ArkTS WebView**:鸿蒙系统的原生 WebView 组件,深度集成于 ArkUI 框架,可调用系统级 API 进行优化[^1]。 #### 2. **性能关键因素** - **渲染引擎**: - Flutter WebView 依赖原生 WebView 的渲染能力,例如 iOS 使用 WebKit,Android 使用 Chromium 内核[^3]。 - ArkTS WebView 基于鸿蒙系统的渲染引擎,可能针对鸿蒙设备(如 GPU 调度、内存管理)进行深度优化。 - **硬件加速**: - 两者均支持硬件加速,但 **ArkTS WebView** 因系统级集成,可能更高效调用 GPU 资源(如 WebGL 渲染 3D 内容)。 - **内存与通信开销**: - Flutter WebView 需通过 **Platform Channel** 实现 Dart 与原生通信,可能增加额外开销。 - ArkTS WebView 作为系统原生组件,通信链路更短,资源调度更直接。 #### 3. **3D 网页支持能力** - **WebGL/Three.js 兼容性**: - Flutter WebView 的兼容性取决于原生 WebView 版本(如 Android 系统需支持 Chromium M84+)。 - ArkTS WebView 需依赖鸿蒙系统对 WebGL 的支持,目前鸿蒙 3.0+ 已完善相关能力。 - **动态加载效率**: - Flutter WebView 加载本地 HTML 资源时性能较优(如通过 `loadFile()` 或 `loadHtmlString()`)[^3][^4]。 - ArkTS WebView 对网络资源的加载可能更高效(如预加载、缓存策略)。 #### 4. **实测场景建议** - **基准测试**:在相同设备(如鸿蒙手机)上对比两者加载同一 3D 页面的帧率、内存占用及启动时间。 - **复杂交互**:测试用户交互(如旋转、缩放 3D 模型)时的响应延迟。 #### 5. **总结** | **维度** | **Flutter WebView** | **ArkTS WebView** | |----------------|----------------------------------------|---------------------------------------| | 跨平台能力 | ✅ 支持 iOS/Android/鸿蒙 | ❌ 仅限鸿蒙设备 | | 系统级优化 | ❌ 依赖原生 WebView 性能 | ✅ 深度集成鸿蒙渲染引擎 | | 3D 渲染流畅度 | ⚠️ 受限于平台 WebView 版本 | ✅ 针对性优化(如 GPU 调度) | | 动态内容适配 | ✅ 支持 CSS/JS 动态调整(需手动适配) | ✅ 系统级自动化适配(如屏幕分辨率) | #### 建议: - 若目标用户主要为 **鸿蒙设备**,优先选择 ArkTS WebView 以获得最佳性能。 - 若需覆盖多平台(iOS/Android/鸿蒙),可接受小幅性能损失,则选择 Flutter WebView---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值