3

I'm trying to write some code for interaction between js and android's WebView.
A already read Building Web Apps in WebView
My goal now is getting some data from js. The appropriate example, that i found there is

Android code:

public class WebAppInterface {

    /** Show a toast from the web page */
    @JavascriptInterface
    public void showToast(String toast) {
        Toast.makeText(getContext(), toast, Toast.LENGTH_SHORT).show();
    }
}

HTML + JS:

<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" />
<script type="text/javascript">
  function showAndroidToast(toast) {
    Android.showToast(toast);
  }
</script>

And ... it works perfect with primitive data (Strings, integers ..) and also arrays of primitive data

But when i try to pass complex objects, as i list below, it cause Java exception "Uncaught Error: Java exception was raised during method invocation", source: file:///android_asset/test.html (34):

Android code:

private class Data {
   String a;
   String b;
}

public class WebAppInterface {

    /** Show a toast from the web page */
    @JavascriptInterface
    public void showToast(Data data) {
        Toast.makeText(getContext(), data.a + data.b, Toast.LENGTH_SHORT).show();
    }
}

HTML + JS:

<input type="button" value="Say hello" onClick="showAndroidToast()" />
<script type="text/javascript">
  var data = {a: "Hello ", b: "world"};
  function showAndroidToast() {
    Android.showToast(data); // exception
  }
</script>

I suppose this occurs because WebView can't define the way to translate JS data types to the Java ones (except of primitive ones).

Can you advise me the way to pass complex data types between JS and android's WebView?

repitch
  • 1,858
  • 1
  • 15
  • 34
  • What do you expect to happen when you send the array? E.g. Android shows a toast "[1, 2, 3]" or it shows a toast for each number one after another? – Tom Alabaster Feb 14 '18 at 10:57
  • method `Android.showToast()` is just an example. Actually, if showToast has `String[] messages` param it works fine. The problem comes with complex data structures (I edited my question) – repitch Feb 14 '18 at 11:25

2 Answers2

1

I found the only easy way: passing this data as json using JSON.stringify():

<input type="button" value="Say hello" onClick="showAndroidToast()" />
<script type="text/javascript">
  var array = [1, 2, 3];
  function showAndroidToast() {
    Android.showToast(JSON.stringify(array)); // "[1, 2, 3]"
  }
</script>

So, then, inside my Java code I can use json parser to represent data in the appropriate way

repitch
  • 1,858
  • 1
  • 15
  • 34
0

showToast is expecting a String, not an array.

You need to make a new method to accept the data type you want e.g. showToast(ArrayList<String> array) or showToast(String[] array).

EDIT

As the question has now been edited to be more specific, I am updating my answer.

Passing custom objects between JavaScript and Java can be done as follows:

public void showToast(String stringData) {
    Data data = new Gson().fromJson(stringData, Data.class);
    // do what you want with the new Data object
}

This uses the Gson library. You could use the default JSON classes used in Android but Gson maps custom object very well. I've had no problems with it.

You then want to use repitch's answer Android.showToast(JSON.stringify(array)); to pass it to the Java method.

I would suggest now calling your custom object Data as the semantics of it aren't specific and could easily lead to confusion.

Here has a good example of converting a JSON array as a string (e.g. from your JavaScript) into a List of your custom objects.

Tom Alabaster
  • 965
  • 6
  • 12
  • yep, for arrays `showToast(String[] array)` works good (ArrayList will cause an error). The problem is working with complex types of data. I make some edits in my question and specified the problem. – repitch Feb 14 '18 at 11:26