在 Android 上使用 addJavascriptInterface() 传递 JavaScript 对象

Posted

技术标签:

【中文标题】在 Android 上使用 addJavascriptInterface() 传递 JavaScript 对象【英文标题】:Passing a JavaScript object using addJavascriptInterface() on Android 【发布时间】:2011-01-16 02:14:45 【问题描述】:

是否可以使用 addjavascriptInterface() 将 JavaScript 对象从 JavaScript 传递到 Java?大致如下:

var javaScriptObject = "field1":"string1", "field2":"string2";
JavaScriptInterface.passObject(javaScriptObject);

如何在 Java 端捕获这样的调用?我设置接口发送字符串没有问题,但是当我发送一个对象时,我在Java端收到null。

【问题讨论】:

注意,确保你的参数不是undefined。我测试过,它没有在 Java 端转换为 null。它变成了字符串“未定义”。 【参考方案1】:

AFAIK,addJavascriptInterface() 仅适用于原始类型和字符串,因此您不能传递任意 Javascript 对象。

【讨论】:

@Robert Siemer:那就使用 JSON。 有谁知道是否有任何文档说明究竟什么可以作为参数,什么可以从作为注入的 java 对象的一部分的方法返回? @WayneUroda:唉,我不知道有任何正式文件。 从我的测试中,您可以传递这些数组的任何原语、字符串。但是,在多态的情况下,似乎接受 float 的方法具有优先级(可能是对方法进行排序的问题)。当我进一步调查时,我会发布一些相关的内容 将javascript对象序列化为json字符串,然后将该字符串传递给android接口。现在将java中的这个json字符串反序列化为java对象。【参考方案2】:

这就是我正在做的......

在安卓中...

@JavascriptInterface
public void getJSONTData(String jsonData) 
      try 
             JSONObject data = new JSONObject(jsonData); //Convert from string to object, can also use JSONArray
           catch (Exception ex) 

在 JavaScript 中...

var obj =  Name : 'Tejasvi', Age: 100;
var str = JSON.stringify(obj);
Android.getJSONTData(str);

到目前为止,我找不到任何其他合适的方法将原生 JavaScript 对象直接传递给 JavascriptInterface。

调用Android.getJSONTData( Name : 'Tejasvi', Age: 100) 会在getJSONTData 中产生null(如果参数类型为Object)或undefined(如果参数类型定义为String)。

【讨论】:

【参考方案3】:

我找到了一个使用 JSON 的解决方案。我的 Java 方法返回一个 JSONArray,在我的 javascript 代码上我收到它并使用 JSON.parse() 转换为 javascript 向量。看例子:

Java:

public class JavaScriptInterface 
Context mContext;
private static int ind=-1;
private static int [] val =  25, 25, 50, 30, 40, 30, 30, 5, 9 ;

public JavaScriptInterface(Context c) 
    mContext = c;


@JavascriptInterface
public JSONArray getChartData() 
    String texto = " [ name: 'valor1', 2007: "+val[(++ind)%9]+", "+
                     " name: 'valor2', 2007: "+val[(++ind)%9]+", "+
                     " name: 'valor3', 2007: "+val[(++ind)%9]+" ]"; 

    JSONArray jsonar=null;
    try 
        jsonar = new JSONArray(texto);
     catch (JSONException e) 
        e.printStackTrace();
    

    return jsonar;


现在是javascript代码:

window.generateData = function() 
        /*var data = [ name: 'valor1', 2007: 50,
                     name: 'valor2', 2007: 20,
                     name: 'valor3', 2007: 30 ];     */
        var data = JSON.parse( Android.getChartData() );
        return data;
    ;

上面的注释代码显示了静态时的情况,现在数据来自 Java 代码。

在 Android 2.1 和 3.2 上进行测试。

【讨论】:

【参考方案4】:

我可以运行这个功能

在 Javascript 中:

var data = 
            'username' : $('#username').val().trim(),
            'password' : $('#password').val().trim(),
            'dns' : $('#dns').val().trim()
        
        var str = JSON.stringify(data);
        Native.getLoginService(str);

在安卓中:

@JavascriptInterface
public void getLoginService(String jsonData)
    try
        JSONObject data = new JSONObject(jsonData);
        String username = data.getString("username");
        String password = data.getString("password");
        String dns = data.getString("dns");

        Log.i("TAG",username + " - " + password + " - " + dns);

    catch (Exception ex)
        Log.i("TAG","error : " + ex);
    

祝你好运……

【讨论】:

【参考方案5】:

我认为你也可以传递 JSONObject 和 JSONArray。所以不仅是原始类型,还有存储在 javascript 数组 [0,1,2] 或字典 one:1, two:2 中的原始类型。

我没有在代码中验证这一点,只是阅读文档。可能很快就会使用它。

【讨论】:

文档在哪里? WebView 的文档中只有一小部分专门介绍它。 我可以确认这一点,但在 JS 空间中,它不是真正的 Javascript 数组。你会得到一个带有length() 和get() 等方法的对象,我只能使用getInt() 等特定的get()。基本上我很确定你在这里得到了一切:json.org/javadoc/org/json/JSONArray.html【参考方案6】:

您不能传递 JSONObject 或 JSONArray,但您可以发送具有该格式的字符串并将它们解析为这些类型。

您的选择是使用字符串公开方法,然后您可以使用 JSONObject 或 JSONArray 来解析字符串并相应地使用它。

这就是我所做的。

@JavascriptInterface
public void passJSON(String array, String jsonObj) throws JSONException

    JSONArray myArray = new JSONArray(array);
    JSONObject myObj = new JSONObject(jsonObj);     
    ...


其中数组是 '["string1","string2"]' 而 jsonObj 是 'attr:1, attr2:"myName"'

【讨论】:

如果示例清晰完整,这可能是一个很好的答案

以上是关于在 Android 上使用 addJavascriptInterface() 传递 JavaScript 对象的主要内容,如果未能解决你的问题,请参考以下文章

在 Android 上使用 RxNetty

无法使用 JavaScript 在 iPhone 上播放声音,但可以在 Android 上播放

Android:在 Android 框架位置 API 上使用 FusedLocationProviderApi 的优缺点是啥?

在android上使用tesseract [关闭]

API 不能在使用 axios 的 React Native 中的旧 Android 设备(Android 7 或更低版本)上工作,但在新设备上工作

在 android 上使用图像精灵