The issue you're encountering stems from the fact that your function is set up to accept a Boolean parameter, yet you're passing it a String parameter at s -> function(s)
. This discrepancy arises because WebView.evaluateJavascript()
defines its input as a String.
You are unable to alter the type of function that webView.evaluateJavascript()
accepts. However, you can convert the String parameter to a Boolean before invoking your function.
Here's an example utilizing your second implementation which accepts a Boolean:
fun evaluateJsFromNative(command: String,
webView: WebView, function: (value : Boolean) -> Unit ) {
webView.evaluateJavascript("(function() { return $command; })();") {
s -> function(s.toBoolean())
}
}
// usage
evaluateJsFromNative(mycommand, mywebview) {
Log.d("SomeTag", "Value=$it")
}
However, this approach is quite straightforward and limited since you could provide any string as a command, not just valid Javascript. The documentation states that evaluateJavascript()
will only execute the function parameter if the Javascript evaluation results in something other than null
(if Javascript is disabled in your WebView, it will pass 'null' to your function). Therefore, even with correct Javascript input, there may still be issues converting s
to a Boolean
. Handling unexpected inputs and types requires significant effort.
If you require a more generic solution, consider the following code snippet, where you need to expand the when
statement to support all relevant types (and implement error handling):
fun <T : Any> evaluateJsFromNative(command: String,
webView: WebView, klass: Class<T>, function: (value : Any?) -> Unit ) {
webView.evaluateJavascript("(function() { return $command; })();") {
s -> if (s.convert(klass) != null) function(s.convert(klass)!!)
}
}
fun <T> String.convert(klass: Class<T>) : Any? {
when (klass.name.toString()) {
"boolean" -> return this.toBoolean()
else -> return null
}
}
// usage
evaluateJsFromNative(mycommand, mywebview, Boolean::class.java) {
Log.d("SomeTag", "Value=$it")
}
In this illustration, you must specify the expected output type from the Javascript, and subsequently parse the result from a string to the specified type. Defining the supported types in advance is necessary. While a simpler conversion method would be preferable, Kotlin lacks such functionality according to discussions on the Kotlin forums.
I trust this clarifies things for you.