11

I am migrating a web application into an android version. After having received and processed JSON data, I have an array of Javascript objects being held within the page.

How can I pass the complete contents of one of the javascript objects "out" to the webview container for display using native android controls ?

Eventually, I could create a javascript interface with a method having parameters for each of the possible javascript object properties - but this appears to be overly heavy.

Can anyone help with this ?

Simon
  • 2,208
  • 4
  • 32
  • 47
  • 1
    Check answers in similar thread http://stackoverflow.com/questions/2250917/passing-a-javascript-object-using-addjavascriptinterface-on-android/32698399#32698399 – Tejasvi Hegde Sep 21 '15 at 15:02

1 Answers1

17

Android's WebView contains a method called addJavascriptInterface(Object obj, String interfaceName) that should be useful here.

Using this method, the object obj that you add as the interface can be accessed via JavaScript code in the Web View. In your case, you could pass in an object that has a setter method that transfers some JavaScript object back to Java.

You'll still need to create the glue code that converts your JavaScript object into the JSON object. For a quick approach, you can just have your interface generate a JSONObject on the Java side using a JSON string passed from JavaScript. The JSONObject class in Java has a constructor that accepts a String containing JSON data. So, you can pass the stringified result directly back to Java and create the object that way. For example:

class JSInterface {
    HashMap<String, JSONObject> mObjectsFromJS = new HashMap<String, JSONObject>();
    public void passObject(String name, String json) {
        mObjectsFromJS.put(name, new JSONObject(json));
    }
}

//At some point, register using:
mJSInterface = new JSInterface();
mWebView.addJavascriptInterface(mJSInterface, "Android");

Then, on the JavaScript side, in the handler that has a blob of unparsed JSON in the variable jsonData:

Android.passObject("pageItems", jsonData);

Now, your JSInterface on the Java side will have a JSONObject containing the items, which you can access using the getters provided by JSONObject. The objects created via the Javascript call will be in the mObjectsFromJS map. You'll of course want to add additional helper methods to the JSInterface class to allow for managing the objects better.

I haven't compiled or tested any of these methods, so you may have to tweak them a bit for proper operation. But hopefully this gives you the idea.

However, if the objects have a consistent interface and data items, it would be more sensible to just create a simple JavaScript glue function that binds the JavaScript object properties to the Java-side object fields using setter methods.

PLEASE NOTE This is giving remote code ability to trigger native code on your device. If you do not have complete control over the pages/scripts being loaded into the WebView, you should ensure that the behavior exposed by obj doesn't allow any exploits.

Jason LeBrun
  • 13,037
  • 3
  • 46
  • 42
  • Thank you Jason, From what you are saying, it is not possible to "simply" pass javascript object directly to a java setter function and expect it to be translated. So, to resume, I would need to : - take my JSON object and revert it back to a json encoded string - pass the encoded string back up through the javascript interface - decode it into a java object All that to be able to access the data correctly. Thank you for clarifying this. – Simon Apr 03 '12 at 07:34
  • After having tried to get this answer to work, I have found out that the javascript interface is completely broken in v2.3.x of Android. Shame. – Simon Apr 30 '12 at 15:31
  • what if I want to make my Java function a constructor, so I would call e.g. `var ob = new Android.MyObject()`, how would I return a native javascript object? – Michael Oct 19 '17 at 00:26