Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Communication between webview and native code in a mobile app

I have to develop an e-commerce mobile app. In order to show the products into the app, I have to use a webview that point to a mobile web site. Associate to each product there is the “add to basket” button. Also this button is an element of the mobile site. In the tab bar (and not in the webview) of the mobile app there is the icon of the basket with the number of elements of the basket. How the webview can know that the user has added one or more element to the basket and send to this information to the native mobile app that can update the icon of the basket?

like image 812
user422688 Avatar asked Feb 21 '14 19:02

user422688


People also ask

How do you communicate between WebView and native Android?

2.1 To receive data from webview ,we can create an interface, which will enable webview to connect the native layer and pass data. From native layer, create a class and replicate the following. While configuring web view, we need to set JavaScript interface as above JSBridge class.

How do you communicate between WebView and react native?

Import the React Native WebView package in App. js . We will create a normal HTML page in WebView and use “script” tags to let the HTML page communicate with the React Native app. In the “script” tag, we are going to call a sendDataToReactNativeApp() function in which we will use a window property called window.

What is the difference between WebView and native?

They get their information from a website rather than from the original surroundings. A webview app does not provide the same seamless experience as a native app because users effectively access a web page. Native apps are also significantly faster because they take advantage of the device's processing capability.

What is WebView and native view?

A WebView is an embeddable browser that a native application can use to display web content. There are a two sets of words to highlight here: The first set of words is native application (aka app).


2 Answers

Javascript. You bind the WebView to your Android application with the JavascriptInterface. Here are some reference docs: Building Web Apps in WebView

like image 147
David C Adams Avatar answered Sep 19 '22 08:09

David C Adams


To call Java (or Kotlin) methods in your Javascript code, first create a class and mark the methods you need to use in Javascript with @JavascriptInterface:

public class WebAppInterface{
    Activity _activity;

    WebAppInterface(Activity context){
        _activity = activity;
    }

    @JavascriptInterface
    public void javaMethodToBeCalledFromJavascript(){
        //Your code here
    }
}

Note that @JavascriptInterface methods must be public, otherwise you can't call them from Javascript.

Then you need to create an instance of that class and pass that instance as an argument to the WebView's addJavascriptInterface:

WebAppInterface interface = new WebAppInterface(this);    //this refers to the current activity
webView.addJavascriptInterface(interface, "Android");

The first argument of addJavascriptInterface is the object with the methods you want to call from Javascript, and the second argument is what the interface will be called in Javascript. Since in this example the second argument is "Android", this will create a Javascript object called Android with the methods that were marked as @JavascriptInterface (if you passed "Foo" as second argument instead, the Javascript object would be called Foo). So to call the javaMethodToBeCalledFromJavascript() method in Javascript, do this:

Android.javaMethodToBeCalledFromJavascript();

The basics are as simple as that. However, there are a few things that are useful to know to avoid spending a lot of time debugging.


The most important thing to know is that Java objects called from Javascript are run on a separate thread. This has two major practical consequences.

First, Android will only let you access UI elements from the UI thread. Therfore, the following code will throw a CalledFromWrongThreadException exception (though it will probably look like it does nothing, I will get to that later):

@JavascriptInterface
public void changeTextOnTextView(String newText){
    _activity.someTextView.setText(newText);
}
Android.changeTextOnTextView("Hello World!");

This is because you can only access _activity.someTextView on _activity's UI thread, but here you're trying to access it from the Javascript thread. To solve this problem, use the activity's runOnUiThread method:

@JavascriptInterface
public void changeTextOnTextView(String newText){
    _activity.runOnUiThread(() -> {
        _activity.someTextView.setText(newText);
    });
}

Second, any uncaught Java exceptions that were thrown from the Javascript thread are treated as Javascript errors. This has multiple issues. The first issue is that by default, Android's WebView doesn't show Javascript errors at all. And even if you solve that (either on the Javascript side with window.onerror or on the Java side as explained in one of the answers here), you will run into the second issue, which is that the Javascript error will only tell you that a "Java exception was raised during method invocation", without giving you any indication whatsoever about what the Java exception was or where in the Java code it was thrown.

To get around this, you can use runOnUiThread as explained above, since uncaught Java exceptions thrown on the UI thread will behave as usual, giving you a detailed stack trace in Android Studio. If you want to catch the exception, you can also use try/catch blocks in your Java code (but not in your Javascript code otherwise you won't be able to get any information about the exception).

like image 44
Donald Duck Avatar answered Sep 22 '22 08:09

Donald Duck