pichillilorenzo / flutter_inappwebview

A Flutter plugin that allows you to add an inline webview, to use a headless webview, and to open an in-app browser window.
https://inappwebview.dev
Apache License 2.0
3.27k stars 1.61k forks source link

Uncaught TypeError: window.flutter_inappwebview.callHandler is not a function, messageLevel: 3} #415

Closed CodeGather closed 4 years ago

CodeGather commented 4 years ago

Environment

Technology Version
Flutter version 1.12.13+hotfix.5
Plugin version ^3.3.0+3
Android version
iOS version
Xcode version

Device information:

Description

Expected behavior:

Current behavior: Uncaught TypeError: window.flutter_inappwebview.callHandler is not a function, messageLevel: 3}

html

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>视频播放</title>
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <link rel="stylesheet" href="index.css">
</head>

<body class="markdown-body">
    <div>
        <div id="dplayer"></div>
    </div>
    <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/flv.js/dist/flv.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/hls.js/dist/hls.min.js"></script>
    <!-- <script src="https://cdn.jsdelivr.net/npm/dashjs/dist/dash.all.min.js"></script> -->
    <!-- <script src="https://cdn.jsdelivr.net/webtorrent/latest/webtorrent.min.js"></script> -->
    <!-- <script src="https://cdn.jsdelivr.net/npm/pearplayer"></script> -->
    <script src="https://cdn.jsdelivr.net/npm/dplayer@1.26.0/dist/DPlayer.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/stats.js"></script>
    <script>
        window.appSendJsData = function(url){
            window.dp = new DPlayer({
                container: document.getElementById('dplayer'),
                video: {
                    url: url || 'https://api.dogecloud.com/player/get.mp4?vcode=5ac682e6f8231991&userId=17&ext=.mp4',
                    pic: 'https://i.loli.net/2019/06/06/5cf8c5d9c57b510947.png',
                    thumbnails: 'https://i.loli.net/2019/06/06/5cf8c5d9cec8510758.jpg',
                    type: 'hls',
                }
            });
            window.dp.fullScreen.request('web');
            window.dp.on('fullscreen', function () {
                console.log('fullscreen');
                window.flutter_inappwebview.callHandler('fullscreen').then(function(result) {
                    console.log(result, typeof result);
                    console.log(JSON.stringify(result), result);
                });
            });
            window.dp.on('fullscreen_cancel', function () {
                console.log('fullscreen_cancel');
                window.dp.fullScreen.request('web');
                window.flutter_inappwebview.callHandler('fullscreen_cancel').then(function(result) {
                    console.log(result, typeof result);
                    console.log(JSON.stringify(result), result);
                });
            });
        }
        window.addEventListener("flutterInAppWebViewPlatformReady", function(event) {
            console.log("初始化")
            window.flutter_inappwebview.callHandler('fullscreen').then(function(result) {
                console.log(result, typeof result);
                console.log(JSON.stringify(result), result);
            });
            window.flutter_inappwebview.callHandler('fullscreen_cancel', 1, true, ['bar', 5], {foo: 'baz'}, result).then(function(result) {
                console.log(result, typeof result);
                console.log(JSON.stringify(result), result);
            });
        });

        function getUrlKey(name) {
            var reg = new RegExp('(^|&|\\?)' + name + '=([^&]*)(&|$|\\?)') // 构造一个含有目标参数的正则表达式对象
            var r = decodeURIComponent(window.location.href).replace(/\+/g, '%20').match(reg) // 匹配目标参数
            if (r != null) return unescape(r[2])
            return null // 返回参数值
        }
    </script>
</body>

</html>

dart

InAppWebView(
                    // initialUrl: "https://youku.cdn7-okzy.com/20191031/15585_f75875d5/index.m3u8", 
                    initialFile: "assets/video/index.html",
                    initialHeaders: {},
                    initialOptions: InAppWebViewGroupOptions(
                      crossPlatform: InAppWebViewOptions(
                        debuggingEnabled: true,
                        clearCache: true,
                        useShouldOverrideUrlLoading: true
                      ),
                    ),
                    onWebViewCreated: (InAppWebViewController controller) {
                      setState(() {
                        webView = controller;
                      });
                      print("onWebViewCreated");
                    },
                    onLoadStart: (InAppWebViewController controller, String url) {
                      print("onLoadStart $url");
                      setState(() {
                        this.url = url;
                      });
                    },
                    shouldOverrideUrlLoading: (controller, shouldOverrideUrlLoadingRequest) async {
                      print("shouldOverrideUrlLoading");
                      return ShouldOverrideUrlLoadingAction.ALLOW;
                    },
                    onLoadStop: (InAppWebViewController controller, String url) async {
                      setState(() {
                        this.url = url;
                      });

                      print('--------${widget.id}');

                      webView.addJavaScriptHandler(handlerName: 'fullscreen', callback: (args) {
                        print("开启全屏"+args.toString());
                      });

                      webView.addJavaScriptHandler( handlerName: 'fullscreen_cancel', callback: (args) {
                        print("取消全屏"+args.toString());
                      });

                      // 发送到JavaScript
                      webView.evaluateJavascript(source: "window.appSendJsData('${playCurrentUrl}')");

                    },
                    onProgressChanged: (InAppWebViewController controller, int progress) {
                      // 页面进度条
                      setState(() {
                        this.progress = progress / 100;
                      });
                    },
                    onUpdateVisitedHistory: (InAppWebViewController controller, String url, bool androidIsReload) {
                      print("页面更新: $url");
                      setState(() {
                        this.url = url;
                      });
                    },
                    onJsAlert: (InAppWebViewController controller, String message) async {
                      print('收到--$message');
                    },
                    onConsoleMessage: (InAppWebViewController controller, ConsoleMessage message){
                      print('打印html数据$message');
                    },
                  )

Steps to reproduce

I/flutter ( 7368): onLoadStart file:///android_asset/flutter_assets/assets/video/index.html
I/flutter ( 7368): 页面更新: file:///android_asset/flutter_assets/assets/video/index.html
I/flutter ( 7368): 打印html数据{message:
I/flutter ( 7368):  %c DPlayer v1.26.0 63275c8 %c http://dplayer.js.org
I/flutter ( 7368):
I/flutter ( 7368): , messageLevel: 1}
I/flutter ( 7368): 打印html数据{message: 初始化, messageLevel: 1}
I/flutter ( 7368): 打印html数据{message: {"isTrusted":false}, messageLevel: 1}
I/flutter ( 7368): 打印html数据{message: {}, messageLevel: 1}
I/flutter ( 7368): 打印html数据{message: {}, messageLevel: 1}
I/flutter ( 7368): 打印html数据{message: Uncaught TypeError: window.flutter_inappwebview.callHandler is not a function, messageLevel: 3}

Images

Stacktrace/Logcat

CodeGather commented 4 years ago

Set debuggingenabled: false,

pichillilorenzo commented 4 years ago

Did you resolve it?

CodeGather commented 4 years ago

@pichillilorenzo yes

chuxia98 commented 4 years ago

i have same error, it's not work when i add debuggingenabled: false in InAppWebViewOptions in android 8 api 26 have this problem , Android 10 is ok

rajashah33 commented 4 years ago

I am also facing same issue.. Please help

chuxia98 commented 4 years ago

I am also facing same issue.. Please help i fix this error use this

const message = "value";
if (window.flutter_inappwebview.callHandler) {
window.flutter_inappwebview.callHandler('handlerName', message);
} else {
/// maybe message type error in flutter, convert to string is work
window.flutter_inappwebview._callHandler('handlerName', setTimeout(function(){}), JSON.stringify([message]));
}
lvisei commented 3 years ago

@chuxia98 @pichillilorenzo @CodeGather Confirmed, Android 10 and iOS 13/14 is ok, android 7 api 24 also have this problem, So this is bug ?