Jon*_*han 29 javascript java android webview
我有一个用Java实现的javascript接口,由我在webview中加载的javascript代码调用.
JS Inside webview:
Android.myFunction(function(data){
console.log(data);
});
Run Code Online (Sandbox Code Playgroud)
Java的:
public class JavaScriptInterface {
Context context;
WebView webView;
JavaScriptInterface(Context c, WebView w) {
context = c;
webView = w;
}
public void myFunction(String callback) {
//when I log callback, it is "undefined"
String someData = "Yay for data";
String js =
"javascript:(function() { "
+ "var callback = " + callback + ";"
+ "callback('" + someData + "');"
+ "})()";
webView.loadUrl(js);
}
}
Run Code Online (Sandbox Code Playgroud)
由webview加载的字符串最终为:
javascript:(function() {var callback = undefined; undefined();})()
Run Code Online (Sandbox Code Playgroud)
我有一些想法:
一个.在JS中构建回调作为字符串.
湾 在将回调传递给Android.myFunction()之前调用回调的toString();
我的问题是,最好的方法是什么?我希望能够将对象传递给Android,它会神奇地运作出来.显然,事实并非如此.;)下一个最好的方法是什么?
cso*_*orn 38
我遇到了类似的问题:在网络应用程序中,我想使用原生的Android确认对话框.这意味着我必须使用确认对话框的结果从Android回调到Javascript部分.
我解决了这个问题如下:
function foo() {
// user confirmation needed
var dataString = <encode data into string>;
MyClient.showConfirmationDialog('myCallBackFunction', dataString, 'A title', 'A message');
}
Run Code Online (Sandbox Code Playgroud)
上面的代码调用Android javascript界面(见下文).javascript提供了回调方法myCallbackFunction(),其名称作为参数传递给Android(以及数据字符串,标题和消息).回调函数如下所示:
function myCallbackFunction(dataString, result) {
var data = <decode data from dataString>;
if (result) {
// user has confirmed
} else {
// user has denied
}
}
Run Code Online (Sandbox Code Playgroud)
在Android方面,我首先在Activity的onCreate()方法中激活Javascript接口:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WebView webView = new WebView(this);
setContentView(webView);
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
webView.addJavascriptInterface(new MyJavascriptInterface(webView), "MyClient");
}
Run Code Online (Sandbox Code Playgroud)
然后执行MyJavascriptInterface创建相应的Android对话框并将结果传递回javascript:
WebView webView;
public MyJavascriptInterface(WebView w) {
this.webView = w;
}
@JavascriptInterface
public void showConfirmationDialog(final String callbackFunction, final String data, String title,
String message) {
Dialog.OnClickListener positiveListener = new Dialog.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
webView.loadUrl("javascript:" + callbackFunction + "('" + data + "', true)");
}
};
Dialog.OnClickListener negativeListener = new Dialog.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
webView.loadUrl("javascript:" + callbackFunction + "('" + data + "', false)");
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle(title).setMessage(message).setPositiveButton("Ok", positiveListener)
.setNegativeButton("Cancel", negativeListener).setCancelable(false);
builder.create().show();
}
Run Code Online (Sandbox Code Playgroud)
将回调函数的名称传递给Android允许使用多个调用确认对话框,每个调用都配有自己的函数来执行实际操作.数据字符串将携带执行操作所需的所有数据(甚至可以包含Json编码的对象).
Dav*_*her 12
您将无法以指定方式传递函数.您将函数传递给Android.myData,但Android.myData接受一个字符串.相反,你可能想要
var myCallback = console.log;
Android.myFunction("myCallback");
Run Code Online (Sandbox Code Playgroud)
您仍然遇到一个问题,即您没有将任何数据传递给回调.虽然这与你的问题没有直接关系,但它会成为一个问题,因为你对字符串问题有相同的强制转换(通过JSON可以解决......但如果Android为你处理那个部分会很好).
最后,您可以将javascript:string缩短为
String js = "javascript:" + callback + "();";
Run Code Online (Sandbox Code Playgroud)
但是,当然,首先测试;)
WebView允许您直接在窗口上下文中执行一些JavaScript。因此,您不需要通过资源URL传递JavaScript。
这是一种将数据传递回html页面的认可方法
/**
* This is an approved way to pass data back to the html page
*/
webView.evaluateJavascript("alert('pass here some ...')", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
}
});
Run Code Online (Sandbox Code Playgroud)
官方文档中的详细信息
在当前显示的页面的上下文中异步评估JavaScript。如果非空,| resultCallback | 将使用该执行返回的任何结果调用。必须在UI线程上调用此方法,并且回调将在UI线程上进行。
兼容性说明。以N或更高版本为目标的应用程序,来自空WebView的JavaScript状态不再跨loadUrl(String)之类的导航持久化。例如,在调用loadUrl(String)之前定义的全局变量和函数在已加载的页面中将不存在。应用程序应该使用addJavascriptInterface(Object,String)代替,以跨导航持久化JavaScript对象。