JavaScript Interface WebView to Android using Live Data

Arul mani
2 min readAug 9, 2020

Hello world,

I have working on my project which is seamlessly communicate HTML page (Includes javascript) which is loaded in WebView. The communication mostly consumes data from API or local DB send back to the WebView to populate in HTML.

Its quite simply explained in this following thread

Then where is the Problem !!!

@JavascriptInterface  
public void setWebViewTextCallback() {
// here !!!
}

The javascript interface we added in WebView and the callback method (Annotated JavascriptInterface) works in Background Thread.

Background thread can’t touch the main thread view that is wroten inscription ancient times.

Solution

Its Simple,

We can run the main thread operation inside using runOnUiThread or Handler or Callback interface.

The most painful thing I'm facing when there is a lot of interface methods is present the runOnUiThread or Handler is hard to maintain and not understandable.

Photo by Amy Elting on Unsplash

Here is the solution,

First in order to communicate javascript to android java class its needs some POJO container for work with LiveData

public class JsData<T> {
private String functionName;
private T data;
private String message;

public JsData(String function, T data) {
this.function = function;
this.data = data;
} // getters, setters... }

JavaScript interface looks like this

public class JavaScriptInterface {

private MutableLiveData<JsData> callback = new MutableLiveData<>();
public JavaScriptInterface() {

}
public LiveData<JsData> getCallback() {
return callback;
}
@JavascriptInterface
public void setWebViewTextCallback(String data) {
// do work in background thread
// API call or DB operation
callback.postValue(new JsData("WebViewText", data))
}}

And Activity be like

public class MainActivity extends AppCompatActivity {   private WebView webView;
private JavaScriptInterface javaJsInterface;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_application);
initWebView();
//...
} private void initWebView() {
webView = findViewById(R.id.app_webview); // ui
//... Other stuffs
// Declaring Javascript interface
javaJsInterface = new JavaScriptInterface();
webView.addJavascriptInterface(javaJsInterface);
// init callback
javaJsInterface.getCallback().observe(this, response -> {
switch(response.getFunction()) {
case "WebViewText":
// do work on main thread
// display or again call evelute
break;
//... more cases
}
});
}}

That's all…

Via this approach, we can easily configure the process WebView in a separate thread and give the UI Main thread handling to LiveData to reduce the burden of handling our own.

--

--