当前位置:   article > 正文

Flutter-用webview_flutter中封装JSBridge_flutter jsbridge

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);
  },
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

需满足以下条件:

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

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

dependencies:  
   webview_flutter: ^4.2.2
  • 1
  • 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)
    );
  }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59

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,
  });
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

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);
        },
      )
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

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']
      });
    }
  };
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/93493
推荐阅读
相关标签
  

闽ICP备14008679号