Cod*_*gue 45 android android-webview android-4.4-kitkat
我正在尝试在Android 4.4中使用新的evaluateJavascript方法,但我得到的所有内容都是null结果:
webView1.evaluateJavascript("return \"test\";", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String s) {
        Log.d("LogName", s); // Log is written, but s is always null
    }
});
如何将结果返回此方法?
更新:更多信息:
setJavascriptEnabled(true);return 'test';,return { test: 'this' }console.log('test'); 正在执行罚款.targetSdkVersion为19:如果您的应用使用WebView设备: Nexus 7和Nexus 5(股票)
Mat*_*unt 65
这个示例中使用了evaluateJavascript方法的示例:
https://github.com/GoogleChrome/chromium-webview-samples/tree/master/jsinterface-example
基本上,如果您在WebView中执行的javascript返回一个值,它将在回调中传递.
需要注意的是,OnReceiveValue中返回的String是JSON值,JSON对象或JSON数组,具体取决于您返回的内容.
需要注意的是,如果返回单个值,则需要在JSON阅读器上使用setLenient(true)才能使其正常工作.
     if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        // In KitKat+ you should use the evaluateJavascript method
        mWebView.evaluateJavascript(javascript, new ValueCallback<String>() {
            @TargetApi(Build.VERSION_CODES.HONEYCOMB)
            @Override
            public void onReceiveValue(String s) {
                JsonReader reader = new JsonReader(new StringReader(s));
                // Must set lenient to parse single values
                reader.setLenient(true);
                try {
                    if(reader.peek() != JsonToken.NULL) {
                        if(reader.peek() == JsonToken.STRING) {
                            String msg = reader.nextString();
                            if(msg != null) {
                                Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show();
                            }
                        }
                    }
                } catch (IOException e) {
                    Log.e("TAG", "MainActivity: IOException", e);
                } finally {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        // NOOP
                    }
                }
            }
        });
    }
您可能仍希望将解析器用于字符串响应的原因是它被转换为JSON值,这意味着它将用引号括起来.
例如,如果你去了:
mWebView.evaluateJavascript("(function() { return 'this'; })();", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String s) {
        Log.d("LogName", s); // Prints: "this"
    }
});
它会打印出这个字符串,用双引号括起来:"this".
其他值得注意的例子:
mWebView.evaluateJavascript("(function() { return null; })();", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String s) {
        Log.d("LogName", s); // Prints the string 'null' NOT Java null
    }
});
mWebView.evaluateJavascript("(function() { })();", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String s) {
        Log.d("LogName", s); //s is Java null
    }
});
mWebView.evaluateJavascript("(function() { return ''; })();", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String s) {
        Log.d("LogName", s); // Prints "" (Two double quotes)
    }
});
Cod*_*gue 11
好的,所以事实证明result这里是Javascript调用的结果 - 好像有人将命令输入Javascript控制台.
所以为了获得结果,它需要包含在一个函数中:
webView1.evaluateJavascript("(function() { return \"this\"; })();", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String s) {
        Log.d("LogName", s); // Prints 'this'
    }
});
这也有效:
webView1.evaluateJavascript("window.variable = \"asd\";", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String s) {
        Log.d("LogName", s); // Prints asd
    }
});
该方法还处理Javascript对象:
webView1.evaluateJavascript("(function() { return { var1: \"variable1\", var2: \"variable2\" }; })();", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String s) {
        Log.d("LogName", s); // Prints: {"var1":"variable1","var2":"variable2"}
    }
});
AndroidJSCore是评估不使用WebView的JavaScript的不错选择.
如果你想坚持使用WebView并且需要在早期版本的Android(4+)上评估JavaScript,这里有一个小库:
https://github.com/evgenyneu/js-evaluator-for-android
jsEvaluator.evaluate("put your JavaScript code", new JsCallback() {
  @Override
  public void onResult(final String result) {
    // get result here (optional)
  }
});
每个人的答案都很棒。我再补充一点。不要像这样使用@JavascripInterface 注释将evaluateJavascript 放在方法中
    @JavascriptInterface  //this is the right annotation
    public void onData(){ 
            mWebView.evaluateJavascript("javascript:executeNext()",null);
    }  
因为它会阻塞 JavaBridge 线程。如果你想把evaluateJavascript放在里面。用这种方式做
    @JavascriptInterface
    public void onData(){
        mWebView.post(new Runnable() {
            @Override
            public void run() {
                mWebView.evaluateJavascript("javascript:executeNext()",null);
            }
        });
    }
总结@GauntFace 的答案并提供不使用 JSON 解析器的替代解决方案:
如果您的 JS 函数只返回 aString并且您想知道为什么该字符串在 Java 中被破坏,那是因为它是 JSON 转义的。
mWebView.evaluateJavascript("(function() { return 'Earvin \"Magic\" Johnson'; })();", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String s) {
        Log.d("LogName", s);
        // expected: s == Earvin "Magic" Johnson
        // actual:   s == "Earvin \"Magic\" Johnson"
    }
});
(请注意,onReceiveValue始终提供一个Stringwhile JS 函数可能会返回 a null,一个 Number 字面量等)
要获得与 JS 中相同的字符串值,如果您 100% 确定您期望String返回正确的值,则需要对它进行 JSON-unescape,例如:
String unescaped = s.substring(1, s.length() - 1)  // remove wrapping quotes
                     .replace("\\\\", "\\")        // unescape \\ -> \
                     .replace("\\\"", "\"");       // unescape \" -> "
但是,请注意,如果 JS 返回正确的,则它s可能是一个字符串,因此您显然需要将其作为第一步进行检查。"null"null
if ("null".equals(s)) {
   ...
} else {
   // unescape JSON
}
| 归档时间: | 
 | 
| 查看次数: | 76770 次 | 
| 最近记录: |