Javascript回调函数传递给Android

我有一个用Java实现的javascript接口,由我在webview中加载的javascript代码调用。

JS Inside webview:

Android.myFunction(function(data){ console.log(data); }); 

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); } } 

由webview加载的字符串最终为:

 javascript:(function() {var callback = undefined; undefined();})() 

我有一些想法:

一个。 在JS中构建回调作为字符串。

湾 在将回调传递给Android.myFunction()之前调用回调的toString();

我的问题是,最好的方法是什么? 我希望能够将对象传递给Android,它会神奇地运作出来。 显然,事实并非如此。 ;)下一个最好的方法是什么?

Solutions Collecting From Web of "Javascript回调函数传递给Android"

您将无法按照指定的方式传递函数。 您将函数传递给Android.myData,但Android.myData接受一个字符串。 相反,你可能想要

 var myCallback = console.log; Android.myFunction("myCallback"); 

您仍然遇到一个问题,即您没有将任何数据传递给回调。 虽然这与你的问题没有直接关系,但它会成为一个问题,因为你将从字符串问题中获得相同的强制转换(通过JSON可以解决……但如果Android为你处理这部分会很好)。

最后,你可以缩短javascript:string to

 String js = "javascript:" + callback + "();"; 

但是,当然,首先测试;)

我遇到了类似的问题:在Web应用程序中,我想使用原生的Android确认对话框。 这意味着我必须使用确认对话框的结果从Android回调到Javascript部分。

我解决了这个问题如下:

 function foo() { // user confirmation needed var dataString = ; MyClient.showConfirmationDialog('myCallBackFunction', dataString, 'A title', 'A message'); } 

上面的代码调用Android javascript界面​​(见下文)。 javascript提供了回调方法myCallbackFunction() ,其名称作为parameter passing给Android(以及数据字符串,标题和消息)。 回调函数如下所示:

 function myCallbackFunction(dataString, result) { var data = ; if (result) { // user has confirmed } else { // user has denied } } 

在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"); } 

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(); } 

将回调函数的名称传递给Android允许使用多个调用确认对话框,每个调用都配有自己的函数来执行实际操作。 数据字符串将携带执行操作所需的所有数据(甚至可以包含Json编码的对象)。

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() { @Override public void onReceiveValue(String s) { } }); 

官方文档的详细信息

在当前显示的页面的上下文中异步评估JavaScript。 如果非null,| resultCallback | 将使用该执行返回的任何结果调用。 必须在UI线程上调用此方法,并且将在UI线程上进行回调。

兼容性说明。 针对N或更高版本的应用程序,来自空WebView的JavaScript状态不再在loadUrl(String)等导航中保留。 例如,在加载的页面中不存在调用loadUrl(String)之前定义的全局variables和函数。 应用程序应使用addJavascriptInterface(Object,String)来跨导航持久化JavaScript对象。

链接到官方WebView文档

据我所知,您所做的只是将Java界面对象添加到您的webview中。 然后,在javascript中,您可以通过调用myJavaInterface.doEchoTest(stringToEcho)来调用它。 附加方法的方式如下:

 myWebView.addJavascriptInterface(MyJavaInterface, "MyJavaInterface"); 

这是java中的接口:

 public class MyJavaInterface{ private WebView mAppView; public MyJavaInterface (WebView appView) { this.mAppView = appView; } public void doEchoTest(String echo){ Toast toast = Toast.makeText(mAppView.getContext(), echo, Toast.LENGTH_SHORT); toast.show(); } } 

所以现在你可以调用JAVA-Android FROM JS了。

要从Java-Android调用JavaScript,您可以调用:

 myWebView.loadUrl("javascript:someJsFunctionICreated("hello javascript!");