Android 与 Vue 双向通信

原生与vue交互其实就是和js交互,方法相同

本来想要使用DSBridge进行通信,但这个作者好像不维护了,引用不了这个库,索性直接使用webview的方法

下面是两个demo的总结,混合开发一般都是vue调用原生方法的情况多。

交互准备

1、vue准备
<div>Android调用js方法!{{ name }}</div> <br />
<div @click="showAndroidToast">点我调用Android方法</div>
data() {
    return {
      name: "i am js",
    };
  },
  methods: {
    // Android调用js方法
    callJsFunction(str) {
      this.name = str;
      return "js调用成功";
    },
    // js调用Android方法
    showAndroidToast() {
      $Android.showToast("哈哈,我是js调用的");
    },
  },
  mounted() {
    //将要给原生调用的方法挂载到 window 上面,方便原生直接调用
    window.callJsFunction = this.callJsFunction;
  },
开启项目,两种方式
  1. npm run serve 运行项目,得到局域网地址:http://10.253.27.224:8080(每个人地址不同,Android与vue项目需在同一个局域网下)
  2. npm run build直接打包项目到dist文件夹,随后将dist文件夹里的内容复制到Android项目里(注意:这里的assets文件夹不是directory,而是带有安卓图标的Folder,后面引入需要用到

android内嵌html android内嵌vue_vue.js

2、Android准备
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <!--引入WebView容器,放置我们的vue页面-->
    <WebView
        android:id="@+id/webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    
</LinearLayout>
AndroidManifest.xml

添加用户许可

<!-- 页面异常 出现Webpage not available,请添加 -->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
使用明文网络流量
<application
        android:allowBackup="true"
        ...
        android:usesCleartextTraffic="true">
		...
    </application>
MainActivity 中的onCreate里
setContentView(R.layout.activity_main);
        super.onCreate(savedInstanceState);
		//引入页面
		setContentView(R.layout.activity_main);

		//webview设置
        WebView webview = findViewById(R.id.webview)
        WebSettings webSettings = webview.getSettings();
        webSettings.setDomStorageEnabled(true);
        webSettings.setJavaScriptEnabled(true);
        webSettings.setBlockNetworkImage(false);

        // 覆盖WebView默认使用第三方或系统默认浏览器打开网页的行为,使网页用WebView打开
        webview.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
//                view.loadUrl(url);
//                return true;
                if (url.startsWith("http:") || url.startsWith("https:") || url.startsWith("ftp")) {
                    view.loadUrl(url);
                    return true;
                } else if (url.startsWith("scheme://")) {
                    // 使用浏览器打开
                    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                    startActivity(intent);
                    return true;
                } else {
                    return false;
                }
            }
            
        //dist打包方式引入  
//      webview.loadUrl("file:///android_asset/index.html");
        //局域网方式引入  
        webview.loadUrl("http://10.253.27.224:8080");
至此,就可以实现Android项目引入vue页面了。

android内嵌html android内嵌vue_android内嵌html_02


一、Android 调用 Vue 方法

  • 原生调用vue方法比较简单,上面准备工作已经在vue中将其方法暴露在window中,只需要在Android中触发调用即可,也可以绑定在安卓按钮中,这里不进行展示。
  • 通过evaluateJavascript()实现
在vue页面加载后进行调用
// webview.setWebViewClient(new WebViewClient() {}里面
@Override
public void onPageFinished(WebView webView, String s) {
    super.onPageFinished(webView, s);
    // 在 onPageFinished 回调里调用,表示页面加载好就调用
    webview.post(new Runnable() {
        @Override
        public void run() {
            webview.evaluateJavascript("javascript:callJsFunction('hello js')", new ValueCallback<String>() {
                @Override
                public void onReceiveValue(String s) {
                    Log.d("MainActivity","js返回的结果: " + s); //日志打印
                }
            });
        }
    });
}
运行app

可以看到日志打印了出来,调用了vue中的函数,而且也通过函数改变了name的值,变成hello js

android内嵌html android内嵌vue_android_03


android内嵌html android内嵌vue_webview_04


二、Vue 调用 原生方法

vue调用原生的方法就稍微比较麻烦,我们要实现在vue页面中点击按钮或者文字,然后调用原生的toast弹框。

1、创建JsJavaBridge类

下面的ToastUtil为封装好的,可以用系统自带的库

public class JsJavaBridge {
    //同步API
    @JavascriptInterface
    public String testSyn(Object msg)  {
        return msg + "[syn call]";
    }

    private Activity activity;
    private WebView webView;

    public JsJavaBridge(Activity activity, WebView webView) {
        this.activity = activity;
        this.webView = webView;
    }

    @JavascriptInterface
    public void onFinishActivity() {
        activity.finish();
    }

    @JavascriptInterface
    public void showToast(String msg) {
        ToastUtil.showToast(msg);
    }
}
2、通过 WebView 设置 Android 类与 JS 代码的映射
webview.addJavascriptInterface(new JsJavaBridge(this, webview), "$Android");

这里将类 JsJavaBridge 在 JS 中映射为了 $Android,所以在 Vue 中可以这样调用 $Android.showToast("哈哈,我是js调用的")

android内嵌html android内嵌vue_vue.js_05

想要了解更多的话可以参考这篇文章

Carson带你学Android:全面总结WebView与 JS 的交互方式