【问题标题】:Android Javascript Interface cannot receive the callback functionAndroid Javascript 接口无法接收回调函数
【发布时间】:2019-05-26 08:13:13
【问题描述】:

我正在使用 kotlin 开发具有 webview 和 webview javascript 的一些功能的本机应用程序。

用户可以点击页面上的按钮,然后调用本机 toast 或警报对话框

我完成了功能,它运行良好,现在我想将callback function添加到对话框中,当用户单击确定按钮(积极按钮)时,它将在网页上运行javascript,

网页上的Javascript

Android.showAlert("Title","Message",function(){alert(123)});

Javascript接口

@JavascriptInterface
    fun showAlert(title:String,msg: String, callBack: Any?) {
        val alertDialog = AlertDialog.Builder(mContext)
        alertDialog.setTitle(title).setMessage(msg)
        alertDialog.setPositiveButton("OK") { _, _->callBack())}
        alertDialog.show()

        Log.d('check',callBack) // Logged callback is null

  }

代码似乎无法接收回调函数,如何解决并运行回调?

谢谢

【问题讨论】:

标签: javascript android kotlin webview


【解决方案1】:
  1. 你不能只记录一个函数,因为在 JavaScript 函数中没有 ID 或地址或类似的东西,存在于其他语言中。要记录它,您必须使用函数 ID 或文本名称显式设置属性或字符串,然后使用它。最好的方法可能是通过文本名称传递回调 - 然后您既可以记录它,也可以实际回调它,请参见以下内容。

  2. 这个网站上的人建议用这种方式在 WebView 中从 Android 调用 JavaScript:

    mWebView.loadUrl("javascript:someFuncInJS();");
    

    但是,有更好和更清洁的方法可以做到这一点,看起来更正确:使用 评估Javascript() 方法。这是使用它的参考成语:

    mWebView.evaluateJavascript("""
        (your javascript code goes here)
    """.trimIndent()) { retv ->
        (and here in Kotlin you can handle return value after the code above will be executed)
    }
    

    在你的情况下,你可以这样写:

    var myCB = "myCallbackFunc1"  // you can get it from previous call from JS
    
    Log.d("check, ${myCB}")
    
    mWebView.evaluateJavascript("""
        ${myCB}();
    """.trimIndent()) { retv ->
    }
    

也请看这个:Kotlin use Java callback interface

编辑: 如果你从你的 Android 程序的 UI 线程(主线程)进行调用,一切都是如此。但是,如果您尝试从运行在不同线程上的 JavascriptInterface 调用内部执行此操作,则会失败。解决方案是始终将 evaluateJavascript() 放在 UI 线程上,如果您需要从另一个线程执行此操作,请使用 View.post {}。这是一个例子:

class WebAppInterface(private val mContext: Context, val mAct: MainActivity) {
    /** Show a toast from the web page  */
    @JavascriptInterface
    fun showToast(toast: String) {
        Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show()

        mAct.mWebView?.post {
            mAct.mWebView?.evaluateJavascript("f1();") { retv ->
                Toast.makeText(mContext, retv, Toast.LENGTH_LONG).show()
            }
        }
    }
}

有关如何操作的完整示例,请查看https://github.com/latitov/Android_WebViewApp_FullScreen

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-07
    • 2019-02-01
    • 1970-01-01
    • 2017-12-20
    • 2018-01-11
    • 2017-12-24
    • 1970-01-01
    相关资源
    最近更新 更多