我想从Android中的Javascript获取返回值.我可以用iPhone做到这一点,但我不能用Android.我使用了loadUrl,但它返回的是void而不是object.有谁能够帮我?谢谢.
Kir*_*kov 67
与Keith更短的答案相同
webView.addJavascriptInterface(this, "android");
webView.loadUrl("javascript:android.onData(functionThatReturnsSomething)");
Run Code Online (Sandbox Code Playgroud)
并实现该功能
@JavascriptInterface
public void onData(String value) {
//.. do something with the data
}
Run Code Online (Sandbox Code Playgroud)
不要忘了删除onData从proguard列表(如果启用的ProGuard)
Fel*_*zin 63
这是一个关于如何实现它的黑客攻击:
将此客户端添加到WebView:
final class MyWebChromeClient extends WebChromeClient {
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
Log.d("LogTag", message);
result.confirm();
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
现在在你的javascript调用中执行:
webView.loadUrl("javascript:alert(functionThatReturnsSomething)");
Run Code Online (Sandbox Code Playgroud)
现在在onJsAlert调用"message"中将包含返回的值.
Com*_*are 18
使用addJavascriptInterface()Java对象添加到JavaScript环境.让您的Javascript调用该Java对象上的方法来提供其"返回值".
Kei*_*ith 11
这就是我今天想出的.它是线程安全的,合理有效的,并允许从Java WebView查看同步Javascript执行.
适用于Android 2.2及更高版本.(需要commons-lang,因为我需要将我的代码片段作为Javascript字符串传递给eval().您可以通过将代码包装在引号中来删除此依赖关系,但是在中function(){})
首先,将其添加到您的Javascript文件中:
function evalJsForAndroid(evalJs_index, jsString) {
var evalJs_result = "";
try {
evalJs_result = ""+eval(jsString);
} catch (e) {
console.log(e);
}
androidInterface.processReturnValue(evalJs_index, evalJs_result);
}
Run Code Online (Sandbox Code Playgroud)
然后,将其添加到您的Android活动中:
private Handler handler = new Handler();
private final AtomicInteger evalJsIndex = new AtomicInteger(0);
private final Map<Integer, String> jsReturnValues = new HashMap<Integer, String>();
private final Object jsReturnValueLock = new Object();
private WebView webView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
webView = (WebView) findViewById(R.id.webView);
webView.addJavascriptInterface(new MyJavascriptInterface(this), "androidInterface");
}
public String evalJs(final String js) {
final int index = evalJsIndex.incrementAndGet();
handler.post(new Runnable() {
public void run() {
webView.loadUrl("javascript:evalJsForAndroid(" + index + ", " +
"\"" + StringEscapeUtils.escapeEcmaScript(js) + "\")");
}
});
return waitForJsReturnValue(index, 10000);
}
private String waitForJsReturnValue(int index, int waitMs) {
long start = System.currentTimeMillis();
while (true) {
long elapsed = System.currentTimeMillis() - start;
if (elapsed > waitMs)
break;
synchronized (jsReturnValueLock) {
String value = jsReturnValues.remove(index);
if (value != null)
return value;
long toWait = waitMs - (System.currentTimeMillis() - start);
if (toWait > 0)
try {
jsReturnValueLock.wait(toWait);
} catch (InterruptedException e) {
break;
}
else
break;
}
}
Log.e("MyActivity", "Giving up; waited " + (waitMs/1000) + "sec for return value " + index);
return "";
}
private void processJsReturnValue(int index, String value) {
synchronized (jsReturnValueLock) {
jsReturnValues.put(index, value);
jsReturnValueLock.notifyAll();
}
}
private static class MyJavascriptInterface {
private MyActivity activity;
public MyJavascriptInterface(MyActivity activity) {
this.activity = activity;
}
// this annotation is required in Jelly Bean and later:
@JavascriptInterface
public void processReturnValue(int index, String value) {
activity.processJsReturnValue(index, value);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
@Felix Khazin建议的解决方案有效,但有一个关键点缺失.
应该在WebView加载网页后进行javascript调用.将此添加WebViewClient到WebView,以及WebChromeClient.
完整示例:
@Override
public void onCreate(Bundle savedInstanceState) {
...
WebView webView = (WebView) findViewById(R.id.web_view);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new MyWebViewClient());
webView.setWebChromeClient(new MyWebChromeClient());
webView.loadUrl("http://example.com");
}
private class MyWebViewClient extends WebViewClient {
@Override
public void onPageFinished (WebView view, String url){
view.loadUrl("javascript:alert(functionThatReturnsSomething())");
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
}
private class MyWebChromeClient extends WebChromeClient {
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
Log.d("LogTag", message);
result.confirm();
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
在API 19+,要做到这一点的最好方法是调用evaluateJavascript您的WebView:
webView.evaluateJavascript("foo.bar()", new ValueCallback<String>() {
@Override public void onReceiveValue(String value) {
// value is the result returned by the Javascript as JSON
}
});
Run Code Online (Sandbox Code Playgroud)
更详细的相关答案:https : //stackoverflow.com/a/20377857
| 归档时间: |
|
| 查看次数: |
83535 次 |
| 最近记录: |