Android Javascript Interface无法接收回调函数

时间:2019-05-26 08:13:13

标签: javascript android kotlin webview

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

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

我完成了功能并使其正常工作,现在我想在对话框中添加callback function,当用户单击“确定”按钮(正按钮)时,它将在网页上运行javascript,

网页上的Javascript

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

JavascriptInterface

@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

  }

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

谢谢

1 个答案:

答案 0 :(得分:0)

  1. 您不能只记录一个函数,因为在JavaScript函数中,没有其他语言上的ID或地址或类似的名称。要记录它,您必须使用函数ID或文本名称显式设置一个属性或字符串,然后使用它。最好的方法可能是通过文本名称传递回调-然后可以将其记录下来,然后实际进行回调,请参见下文。

  2. 此网站上的人们建议使用这种方法从Android调用WebView中的JavaScript:

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

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

    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

编辑: 就是这样, if 是您从Android程序的UI线程(主线程)进行调用。但是,如果尝试从运行在不同线程上的JavascriptInterface调用中执行此操作,则它将失败。解决方案是始终将评估Javascript()放在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

希望有帮助。