Js and native interaction is divided into two cases: JS calls native methods, native calls JS methods.
This article will explain the two cases respectively, H5 end with VUE implementation.
I. Preliminary Preparation (Vue project preparation)
The H5 side of this article is implemented using Vue, so get the Vue project environment ready before you start.
After the project is written, run the NPM run serve command to start the project.
http://localhost:8080/ and http://10.0.0.188:8080/
10.0.0.188 is the IP address of my machine. Everyone’s IP address is different.
Either is fine if you want to access it from your computer’s browser, but use a second one with an IP address if you want to access it from your phone or emulator, and make sure your phone is connected to the same wifi or network segment as your computer.
Note: vuE-cli 3.0 is used here, running the command is different from vue-cli 2.X. Please consult the official documentation for details.
After successful startup, you can configure http://10.0.0.188:8080/ address to WebView in the Android project
Intent intent = new Intent(getActivity(), ProgressWebviewActivity.class);
intent.putExtra("url"."http://10.0.0.188:8080/");
startActivity(intent);
Copy the code
At this point, you can access the Vue project from your phone.
2, Android native call JS methods
Android calls JS in two ways, both via WebView methods:
webview.loadUrl()
webview.evaluateJavascript()
Differences between the two:
LoadUrl () refreshes the page, but evaluateJavascript() does not, so evaluateJavascript() is more efficient
LoadUrl () does not get the js return, evaluateJavascript() does
EvaluateJavascript () is available after Android 4.4
Effects to be achieved:
As shown in the picture below, there is a line of text “haha” on the page. When the WebView page is loaded, the line should be changed to “I changed the text through the native method” + the parameter passed by Android, and a string “JS call successful” should be returned to Android.
2.1 the Vue code
How to write the code in Vue first
mounted() {
// The method to be called native will be mounted on the window
window.callJsFunction = this.callJsFunction
},
data() {
return {
msg: "Ha ha"}},methods: {
callJsFunction(str) {
this.msg = "I changed the text by native means." + str
return "Js call successful"}}Copy the code
In methods, define a method called callJsFunction(STR) for Android to call, which takes an argument STR and changes the text on the page.
If you just define a method in methods, the native call will not find the method. So mount the method on the window when the page loads so that the WebView can get hold of it. Notice, this step is very important to write!
Note one detail: this. CallJsFunction should not be followed by parentheses (). Parentheses are equivalent to calling directly.
To sum up, there are two steps to do in Vue:
- in
methods
Method defined in - in
mounted
Mount the method inwindow
上
2.2 Code in Android
You need to wait until the page is loaded to write the call logic in the onPageFinished method of the WebView, otherwise it will not execute.
2.2.1 loadUrl()
implementation
tbsWebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url, headerMap);
return true;
}
@Override
public void onPageFinished(WebView webView, String s) {
super.onPageFinished(webView, s);
// Android calls the js method. Note that it needs to be called in the onPageFinished callback
tbsWebView.post(new Runnable() {
@Override
public void run(a) {
tbsWebView.loadUrl("javascript:callJsFunction('soloname')"); }}); }}); }});Copy the code
If no parameter is not required, remove the parameters can be tbsWebView. LoadUrl (” javascript: callJsFunction () “);
2.2.2 evaluateJavascript()
implementation
Other places with the loadUrl (), just put tbsWebView. LoadUrl (” javascript: callJsFunction (‘ soloname ‘) “); replace
@Override
public void onPageFinished(WebView webView, String s) {
super.onPageFinished(webView, s);
// Android calls the js method. Note that it needs to be called in the onPageFinished callback
tbsWebView.post(new Runnable() {
@Override
public void run(a) {
tbsWebView.evaluateJavascript("javascript:callJsFunction('soloname')".new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Logger.d("Js returns result:"+ s); }}); }}); }Copy the code
You can see that the page is updated, and the second method gets the result returned.
JS calls Android native methods
There are three ways to call Android code with JS:
- through
WebView
的addJavascriptInterface()
Object mapping - through
WebViewClient
的shouldOverrideUrlLoading()
Method callback intercepts url - through
WebChromeClient
的onJsAlert()
,onJsConfirm()
,onJsPrompt()
Method callback intercepts the JS dialog boxalert()
,confirm()
,prompt()
The message
Comparison: The first is the simplest, but has bugs below Android 4.2; The second and third are complex to use, but do not have bug problems.
Because the current device system version is basically above 4.2, so the first kind can be used, simple and quick. Time is limited in this article only to achieve the first, the second and the third will not be implemented, want to know can refer to this article.
3.1 Effect Display
The effect is to click the button on the H5 page to pop up the Android native Toast
3.2 the Vue code
methods: {
showAndroidToast() {
$App.showToast("Ha ha, I'm calling from JS.")}}Copy the code
Define the method showAndroidToast() in methods and call it when you click the button “Call Android native Toast” on the page.
3.3 the Android code
A new kind of JsJavaBridge
public class JsJavaBridge {
private Activity activity;
private WebView webView;
public JsJavaBridge(Activity activity, WebView webView) {
this.activity = activity;
this.webView = webView;
}
@JavascriptInterface
public void onFinishActivity(a) {
activity.finish();
}
@JavascriptInterface
public void showToast(String msg) { ToastUtils.show(msg); }}Copy the code
Then set up the mapping between Android class and JS code through WebView
tbsWebView.addJavascriptInterface(new JsJavaBridge(this, tbsWebView), "$App");
Copy the code
Here the JsJavaBridge class is mapped to $App in JS, so in Vue you can call $app.showtoast like this (” ha ha, I am called by JS “).
This is how Android and JS call each other.