[英]Executing arbitrary javascript from Android WebView callback/interface
我已經使用Android的WebView設置了一個非常簡單的javascript實現:
index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript" charset="utf-8" src="Test.js"></script>
</head>
</html>
MyJavaScript.java
public class MyJavaScript
{
public MyJavaScript()
{
// create the WebView
mWebView = new WebView(mContext);
// enable javaScript
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
// add javaScript interface
mWebView.addJavascriptInterface(new JavaScriptTest, "_test");
// load our dummy page
mWebView.loadUrl("file:///android_asset/javascript/index.html");
}
public void exec(String script)
{
mWebView.loadUrl("javascript:" + script);
}
}
Test.js
function Test()
{
};
Test.prototype.foo = function()
{
window._test.foo();
};
Test.prototype.bar = function()
{
window._test.bar();
};
var test = new Test();
JavaScriptTest.java
public class JavaScriptTest
{
public void foo()
{
Log.d("Test", "foo");
}
public void bar()
{
Log.d("Test", "bar");
}
}
當呼叫者撥打類似的內容時:
MyJavaScript.exec("foo();");
執行最終會傳播到JavaScriptTest.foo()。 該執行在WebView的工作線程中。
我想在JavaScriptTest.foo()中做的事情類似於eval(“ bar();”);。 我基本上想從Java回調/接口同步執行更多的javascript。 也就是說,我希望在返回JavaScriptTest.foo()之前完全執行javascript bar()方法。 我不知道該怎么做。
如果備份一層,則調用bar()很簡單; 來自Test.js中的foo方法。 但是,這並不能真正滿足我的需求。 我需要能夠執行JavaScriptTest.foo()中的JavaScriptTest.foo()發現的任意javascript。
而且因為JavaScripTest.foo()在WebView的工作線程中執行,所以將JavaScriptTest.foo()發現的任意javascript傳遞給WebView.loadUrl(...)都不起作用,因為您需要從UI線程調用該API。
理想情況下,在WebView的工作線程中執行的Java回調/接口存根中,將有一種方法可以執行一些任意javascript。
我可能可以通過將任意javascript傳遞回Test.js中的foo()來解決該問題,但這將是比我的首選更為通用和丑陋的解決方案。 如果我的第一選擇不存在,那么我沒有選擇。
由於WebView的線程要求,恐怕您無法實現所需的功能。 從后台線程在Java中開始新的javascript執行的唯一方法是將任務發回到UI線程,但這會破壞您的同步需求。
我認為您唯一的選擇是讓Java對象將String返回給您的JavaScript,然后進行評估(如您所建議的那樣,我認為)。
您可以修改JavaScriptTest接口以返回要評估的javascript。
public class JavaScriptTest
{
public String foo()
{
return "bar();"
}
public void bar()
{
Log.d("Test", "bar");
}
}
然后在您的JavaScript中:
function Test()
{
};
Test.prototype.foo = function()
{
eval(window._test.foo());
};
Test.prototype.bar = function()
{
window._test.bar();
};
var test = new Test();
返回之前不會對bar()求值,但是之后可以立即執行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.