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?

2
  • 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? Commented Feb 14, 2018 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) Commented Feb 14, 2018 at 11:25

2 Answers 2

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

Sign up to request clarification or add additional context in comments.

Comments

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.

1 Comment

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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.