I'm mencoba untuk menggunakan yang baru evaluateJavascript metode di Android 4.4, tapi semua yang pernah saya dapatkan kembali adalah null hasilnya:
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
}
});
Bagaimana saya mengembalikan hasil untuk metode ini?
Update: Sedikit info lebih lanjut:
setJavascriptEnabled(true);
kembali 'test';
,kembali { tes: 'ini' }
konsol.log('test');
sedang dijalankan baik-baik saja.targetSdkVersion
ke 19 sebagai per: Jika aplikasi anda menggunakan WebViewPerangkat: Kedua Nexus 7 dan Nexus 5 (Saham)
Ada contoh evaluateJavascript metode yang digunakan dalam contoh ini:
https://github.com/GoogleChrome/chromium-webview-samples/tree/master/jsinterface-example
Pada dasarnya jika javascript anda jalankan di WebView mengembalikan nilai itu'akan berlalu di balik.
Hal utama yang perlu diperhatikan adalah bahwa String yang dikembalikan dalam OnReceiveValue adalah berupa JSON Nilai, Objek JSON atau JSON Array tergantung pada apa yang anda kembali.
Hal-hal yang perlu diperhatikan tentang hal ini jika anda mengembalikan nilai tunggal, anda perlu menggunakan setLenient(benar) pada JSON reader untuk itu untuk bekerja.
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
}
}
}
});
}
Alasan anda mungkin masih ingin menggunakan parser untuk string respon itu dikonversi ke JSON nilai yang berarti itu akan dibungkus dalam tanda kutip.
Misalnya jika anda pergi:
mWebView.evaluateJavascript("(function() { return 'this'; })();", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("LogName", s); // Prints: "this"
}
});
Ini akan mencetak string ini, dibungkus dengan tanda kutip ganda: "ini".
Contoh lain yang patut dicatat:
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)
}
});
OK, jadi ternyata hasil
di sini adalah hasil dari Javascript panggilan - seperti jika seseorang memasukkan perintah ke dalam konsol Javascript.
Jadi dalam rangka untuk mendapatkan hasil, itu harus dibungkus dalam sebuah fungsi:
webView1.evaluateJavascript("(function() { return \"this\"; })();", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("LogName", s); // Prints 'this'
}
});
Ini juga akan bekerja:
webView1.evaluateJavascript("window.variable = \"asd\";", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("LogName", s); // Prints asd
}
});
Metode ini juga menangani objek 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 adalah alternatif yang baik untuk mengevaluasi JavaScript yang tidak menggunakan WebView.
Jika anda ingin tetap dengan WebView dan perlu untuk mengevaluasi JavaScript pada versi sebelumnya (Android 4+), berikut adalah sedikit perpustakaan:
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)
}
});
Untuk meringkas jawaban dari @GauntFace dan memberikan alternatif solusi tanpa menggunakan JSON parser:
Jika anda JS kembali fungsi hanya String
dan're-tanya tentang mengapa string hancur di pulau Jawa, it's karena itu's JSON-lolos.
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"
}
});
(perhatikan bahwa onReceiveValue
menyediakan String
sementara JS fungsi dapat mengembalikan null
, Sejumlah literal dll.)
Untuk mendapatkan nilai string yang sama seperti di JS, jika anda'kembali 100% yakin anda're mengharapkan tepat String
kembali, kau'd perlu JSON-unescape itu, misalnya seperti:
String unescaped = s.substring(1, s.length() - 1) // remove wrapping quotes
.replace("\\\\", "\\") // unescape \\ -> \
.replace("\\\"", "\""); // unescape \" -> "
Namun, perhatikan bahwa s
mungkin string "null"
jika JS kembali tepat null
, jadi anda jelas perlu memeriksa bahwa sebagai langkah pertama.
if ("null".equals(s)) {
...
} else {
// unescape JSON
}
Semua orang's jawaban yang lebih besar. Saya hanya menambahkan satu poin lagi. Don't menempatkan evaluateJavascript dalam metode dengan @JavascripInterface penjelasan seperti ini cara
@JavascripInterface public void onData(){ mWebView.evaluateJavascript("javascript:executeNext()",null); }
Karena itu akan memblokir JavaBridge Benang.
jika anda ingin menempatkan evaluateJavascript di dalamnya. Melakukannya dengan cara ini
``
@JavascripInterface
public void onData(){
mWebView.posting(new Runnable() {
@Override
public void run() {
mWebView.evaluateJavascript("javascript:executeNext()",null);
}
});
} ``