我们如何在我们的 android 应用程序中执行一个 javascript 函数并获得一个返回值?
Posted
技术标签:
【中文标题】我们如何在我们的 android 应用程序中执行一个 javascript 函数并获得一个返回值?【英文标题】:How we can execute a javascript function and get a return value in our android application? 【发布时间】:2012-11-11 17:34:50 【问题描述】:我们想在按钮按下事件上执行一个javascript,我们需要将参数传递给脚本并获取返回值,所以我们使用“WebChromeClient”来实现这个, 但是我们得到 Exception is "SyntaxError: Parse error at undefined:1"
以下是我的代码
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
public class FirstTab extends Activity
private WebView webView;
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.regis);
try
webView = (WebView) findViewById(R.id.webView1);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebChromeClient(new MyWebChromeClient());
String customhtml = "<html><head><title>iSales</title><script type=\"text/javascript\"> function fieldsOnDelete() var x=123; return \"JIJO\"; </script></head><body>hi</body></html>";
webView.loadData(customHtml, "text/html","UTF-8");
catch(Exception e)
Log.v("JAC LOG",e.toString());
public void onResume()
super.onResume();
final Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new View.OnClickListener()
public void onClick(View v)
try
webView.loadUrl("javascript:alert(javascript:fieldsOnDelete())");
catch(Exception e)
Log.v("JAC LOG",e.toString());
);
final class MyWebChromeClient extends WebChromeClient
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result)
Log.v("LogTag", message);
result.confirm();
return true;
【问题讨论】:
refer this可以帮助您解决问题 【参考方案1】:你可以使用mWebView.loadUrl("javascript:checkName");
来调用方法...
然后您可以使用addJavascriptInterface()
将Java 对象添加到Javascript 环境。让您的 Java 脚本调用该 Java 对象的方法以提供其“返回值”。
EDIT1:或者您可以使用以下技巧:
将此客户端添加到您的 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;
现在在你的 java 脚本调用中做:
webView.loadUrl("javascript:alert(functionThatReturnsSomething)");
现在在 onJsAlert 调用中“message
”将包含返回值。
编辑2:
因此,如果我们在调用加载 URL 之后调用 javascript 方法,则它不起作用,因为页面加载需要时间。所以我创建了一个测试程序来测试它......
以下是我存储在 assets 文件夹中的 html 文件(名为 test.html):
<html>
<head>
<script language="javascript">
function fieldsOnDelete(message)
alert("i am called with " + message);
window.myjava.returnValue(message + " JIJO");
</script>
<title>iSales android</title>
</head>
<body></body>
</html>
</body>
</html>
以下是我的 java 类,我将把它作为接口添加到 java 脚本中,它会接收返回值:
public class MyJS
public void returnValue(String string)
Log.d(this.getClass().getSimpleName(), string);
以下是我的活动课:
public class CheckWebView extends Activity
private WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_check_web_view);
webView = (WebView) findViewById(R.id.webview);
webView.setWebChromeClient(new WebChromeClient()
@Override
public void onConsoleMessage(String message, int lineNumber,
String sourceID)
super.onConsoleMessage(message, lineNumber, sourceID);
Log.d(this.getClass().getCanonicalName(), "message " + message
+ " :::line number " + lineNumber + " :::source id "
+ sourceID);
@Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage)
// TODO Auto-generated method stub
onConsoleMessage(consoleMessage.message(),
consoleMessage.lineNumber(), consoleMessage.sourceId());
Log.d(this.getClass().getCanonicalName(), "message::::: "
+ consoleMessage.message());
return super.onConsoleMessage(consoleMessage);
);
webView.addJavascriptInterface(new MyJS(), "myjava");
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setPluginsEnabled(true);
webView.getSettings().setAllowFileAccess(true);
webView.loadUrl("file:///android_asset/test.html");
@Override
public boolean onCreateOptionsMenu(Menu menu)
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_check_web_view, menu);
return true;
/* (non-Javadoc)
* @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
*/
@Override
public boolean onOptionsItemSelected(MenuItem item)
webView.loadUrl("javascript:fieldsOnDelete('name');");
return super.onOptionsItemSelected(item);
这里的关键是调用从 assets 文件夹加载 html 文件和调用 javascript:method
之间应该有一些时间间隔。在这里,我从onOptionsItemSelected
调用它,它工作正常。如果我将webView.loadUrl("javascript:fieldsOnDelete('name');");
移动到onCreate() 方法的末尾,它会显示错误,它找不到fieldsOnDelete()
方法...
希望对你有帮助...
EDIT3:
在您的代码中替换以下内容
webView.loadUrl("javascript:alert(javascript:fieldsOnDelete())");
与
webView.loadUrl("javascript:alert(fieldsOnDelete())");
然后尝试...
【讨论】:
我们没有 url,我们将 javascript 保存在一个字符串变量中。例如: String customHtml = "webView.loadData(customHtml, "text/html", "UTF-8");
后尝试调用mWebView.loadUrl("javascript:checkName");
我们尝试了 webView.loadUrl("javascript:alert(javascript:fieldsOnDelete())");获取返回值,但我们在 Web 控制台标签中收到“SyntaxError: Parse error at undefined:1”消息,但它对 webView.loadUrl("javascript:var x=123;alert(x)");
这是一个愚蠢的 Web 视图计时问题......我能够运行它......在 5 分钟内更新答案......
已经在答案中发布了工作演示代码......你试过了吗?【参考方案2】:
在 Android KitKat 中有一个新方法 evaluateJavascript,它有一个返回值的回调。回调根据您返回的内容返回 JSON 值、对象或数组。
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
);
您可以在此处查看完整示例:https://github.com/GoogleChrome/chromium-webview-samples/tree/master/jsinterface-example
【讨论】:
以上是关于我们如何在我们的 android 应用程序中执行一个 javascript 函数并获得一个返回值?的主要内容,如果未能解决你的问题,请参考以下文章
Android_一如何获取linux中的可执行文件指令之Termux使用介绍
如何在不减慢执行速度的情况下分析 Android 应用程序的执行?
Android_二使用Termux编译Android平台所需的linux可执行文件指令之nmap