Flutter WebView Communication(web with vue.js)

发布于 2025-02-12 12:23:55 字数 3227 浏览 1 评论 0原文

#我尝试过的

  1. 我在vscode中使用vue.js制作了一个网页,然后将网页部署到localhost:8080
  2. 在Android Studio中制作了一个本机应用程序,并带有
  3. 从WebView到Flutter Aptial App

######问题?

当我在WebView中单击BTN以将消息发送到Flutter应用程序时 在V-ON处理程序中发生错误:“ TypeError:无法读取NULL的属性(读取'Postmessage')”

###Web代码(vscode中的vue.js)

1。 main.js

import Vue from 'vue'
import App from './App.vue'
import message from './message'; 

Vue.config.productionTip = false

Vue.use(message);
window.sendMessage = message; 

new Vue({
  render: h => h(App)
}).$mount('#app')
  1. message.js
const sendMessage = (message) => {

    if (userAgent.indexOf('android') !== -1) {
      return WebViewBridge.postMessage(message);;

    } else if (userAgent.indexOf('iphone') !== -1 || userAgent.indexOf('ipad') !== -1) {
      return window.webkit.messageHandlers.webViewMessageHandler.postMessage(message);

    } else { 
       return window.opener.postMessage(message);
    }
  }
export default {sendMessage}
  1. app.vue
<template>
  <div class="main">
    <div class="btn" @click="toast()">communicate!</div>
  </div>
</template>

<script>
import message from "../src/message.js"

export default {
  name: 'App',
  methods:{
    toast(){
      console.log("message to Flutter App!")
      message.sendMessage("hello")
    }
  },
};
</script>
<style>
.main{
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: antiquewhite;
}
.btn{
  background-color: black;
  color: #fff;
  padding: 10px 20px;
  border-radius: 10px;
}
</style>

#flutter代码(在Android Studio)

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';


void main() => runApp(

  MaterialApp(
    title: 'Navigator',
    initialRoute: '/my',
    routes: {
      "/my":  (context) => MyApp(),
    },

  ),

);

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: EmptyAppBar(), 
        body: WebView(
          //userAgent: "random", //Add this to resolve issue
            initialUrl: "http://myipaddress:8080/",
            javascriptMode: JavascriptMode.unrestricted,
            //A named channel for receiving messaged from JavaScript code running inside a web view
            javascriptChannels: <JavascriptChannel>{
              _webToApp(context),
            }
        )
    );
  }
}

// Webview Native commuication
JavascriptChannel _webToApp(BuildContext context) {
  return JavascriptChannel(
      name: 'WebViewBridge',
      // A callback that's invoked when a message is received through the channel.
      onMessageReceived: (JavascriptMessage message) {
        print('javascript run');


      });
}

# What I tried

  1. I made a webpage with vue.js in VScode and Deploy Web page to localhost:8080
  2. Made a Native App in Android Studio with Flutter
  3. toast message from webview to Flutter Native App

# Problem?

when I click btn in Webview to send message to Flutter App
Error occured Error in v-on handler: "TypeError: Cannot read properties of null (reading 'postMessage')"

# Web Code (vue.js in VScode)

1.main.js

import Vue from 'vue'
import App from './App.vue'
import message from './message'; 

Vue.config.productionTip = false

Vue.use(message);
window.sendMessage = message; 

new Vue({
  render: h => h(App)
}).$mount('#app')
  1. message.js
const sendMessage = (message) => {

    if (userAgent.indexOf('android') !== -1) {
      return WebViewBridge.postMessage(message);;

    } else if (userAgent.indexOf('iphone') !== -1 || userAgent.indexOf('ipad') !== -1) {
      return window.webkit.messageHandlers.webViewMessageHandler.postMessage(message);

    } else { 
       return window.opener.postMessage(message);
    }
  }
export default {sendMessage}
  1. App.vue
<template>
  <div class="main">
    <div class="btn" @click="toast()">communicate!</div>
  </div>
</template>

<script>
import message from "../src/message.js"

export default {
  name: 'App',
  methods:{
    toast(){
      console.log("message to Flutter App!")
      message.sendMessage("hello")
    }
  },
};
</script>
<style>
.main{
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: antiquewhite;
}
.btn{
  background-color: black;
  color: #fff;
  padding: 10px 20px;
  border-radius: 10px;
}
</style>

# Flutter Code (in Android Studio)

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';


void main() => runApp(

  MaterialApp(
    title: 'Navigator',
    initialRoute: '/my',
    routes: {
      "/my":  (context) => MyApp(),
    },

  ),

);

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: EmptyAppBar(), 
        body: WebView(
          //userAgent: "random", //Add this to resolve issue
            initialUrl: "http://myipaddress:8080/",
            javascriptMode: JavascriptMode.unrestricted,
            //A named channel for receiving messaged from JavaScript code running inside a web view
            javascriptChannels: <JavascriptChannel>{
              _webToApp(context),
            }
        )
    );
  }
}

// Webview Native commuication
JavascriptChannel _webToApp(BuildContext context) {
  return JavascriptChannel(
      name: 'WebViewBridge',
      // A callback that's invoked when a message is received through the channel.
      onMessageReceived: (JavascriptMessage message) {
        print('javascript run');


      });
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

也只是曾经 2025-02-19 12:23:55

AS-IS

WebViewBridge.postMessage(消息);

to-be

// eslint-disable-next-line

窗口.webviewbridge.postmessage(message);

AS-IS

WebViewBridge.postMessage(message);

TO-BE

// eslint-disable-next-line

window.WebViewBridge.postMessage(message);

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文