Android 来自 Vue.js 应用程序的 JS Bridge

Android JS Bridge from Vue.js application

我有一个 vue.js 应用程序 运行 在 Android 7.1.1 的 WebView 中。单击 vue.js 时有一个 <div> 按钮,我希望它在 Android 应用程序中调用本机函数。我已经能够在没有 vue.js 的情况下使用一个简单的 .html 文件和 <javscript>.

来做到这一点

我已将其用作资源,但它不起作用。 http://www.programmersought.com/article/8455235099/

Android 应用程序 activity

package myapp;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private WebView webView;

    @SuppressLint("SetJavaScriptEnabled")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);

        webView = findViewById(R.id.webView);
        webView.setWebViewClient(new WebViewClient() {

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                webView.addJavascriptInterface(new JsJavaBridge(), "$App");
            }
        });

        //webView.setWebViewClient(new WebViewClient());

        // This works
        //webView.loadUrl("file:///android_asset/test.html");

        // This does NOT work - Vue.js app running on my local machine
        webView.loadUrl("http://192.168.0.17:3000");

        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);
    }

    public class JsJavaBridge {

        public JsJavaBridge() {

        }

        @JavascriptInterface
        public void onFinishActivity() {
        }

        @JavascriptInterface
        public void printTicket(String msg) {
            // Want to call this via the vue.js app
            Toast.makeText(getApplicationContext(), "msg",  Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onBackPressed() {
        if(webView.canGoBack()) {
            webView.goBack();
        }else {
            super.onBackPressed();
        }
    }
}

Vue.js 文件

<template>
  <div>
    <Navbar />
    <div class="container">
      <h1>Support</h1>
      <div class="btn btn-secondary" @click="printTicket"><i class="fas fa-print ticket"></i>Print Test Ticket</div>
    </div>
  </div>
</template>
<script>
import Navbar from '@/components/Navbar';

export default {
  components: {
    Navbar
  },
  mounted: function() {},
  methods: {
    printTicket: function() {
      try {
        // eslint-disable-next-line no-undef
        $App.printTicket('HELLO');
      } catch (error) {
        console.error(error);
      }
    }
  }
};
</script>
<style scoped>
.ticket {
  padding-right: 1rem;
}
.btn {
  padding: 0.75rem;
}
</style>

我能够让它工作。在 Android 应用程序代码库中。

public class MainActivity extends AppCompatActivity {

    private WebView webView;

    private static final String url = "https://url-to-vue-app.com"

    @SuppressLint("SetJavaScriptEnabled")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);

        webView = findViewById(R.id.webView);

        webView.loadUrl(url);

        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);

        webView.addJavascriptInterface(new JsJavaBridge(), "printer");
    }
}

在vue app代码库中如下。

    try {
      // eslint-disable-next-line no-undef
      if (printer) {
        // eslint-disable-next-line no-undef
        printer.printTicket('Hello World');
      }
    } catch (error) {
      reject(error);
    }