Background - We use Grafana to show some data on app in a webview. But Grafana is not supported older version of webviews hence we decided to inject a JS code to detect if Grafana can be run on this version or not and generate corresponding event. On some webview versions I am not getting the callback at all but on some webview version I can get the callback only if I inject the script in onPagestarted.
Following are two places where I can inject JS code either in onPageStarted or in onPageFinished. Both the place same JS function is injected(EVENT_HANDLER_JS).
binding?.viewWeb?.webViewClient = object : WebViewClient() {
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
binding?.webProgress?.visibility = View.VISIBLE
binding?.viewWeb?.loadUrl(EVENT_HANDLER_JS)
eventCallback?.onPageReloadStatus(PageReloadStatus.Loading)
}
override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url)
binding?.webProgress?.visibility = View.GONE
binding?.viewWeb?.loadUrl(EVENT_HANDLER_JS)
eventCallback?.onPageReloadStatus(PageReloadStatus.Success)
}
}
But in older APIs(27, more dependent on webview version than API level) injection in onPageFinished is not able to invoke the JSInterface.
const val EVENT_HANDLER_JS = "javascript:(function() {" +
"function receiveMessage(event) {\n" +
"$JS_INTERFACE_NAME.receiveMessage(JSON.stringify(event.data));\n" +
"}" +
"window.addEventListener(\"message\", receiveMessage, false);"+
"})()"
The problem with injecting into both places are that events are recieved twice in the JSInterface(In newer API).
Is there any way to
- Know about different behaviours of injecting JS into onPageStarted or onPageFinished functions(I feel like the postEventMessage from JS side is not finding the correct object(window.parent or something))
- Any way to avoid injecting JS if it's already injected?