Creé una aplicación de Android y cargué un archivo html en Android webView. Que se carga con éxito y funciona bien.
class MainActivity : AppCompatActivity() { private lateinit var myAndroidWebView: WebView; @SuppressLint("SetJavaScriptEnabled") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) setWebviewDetails(); } private fun setWebviewDetails(){ //if(!::myAndroidWebView.isInitialized){ myAndroidWebView = findViewById(R.id.webView); //} myAndroidWebView.settings.javaScriptEnabled = true; myAndroidWebView.loadUrl("file:///android_asset/App/index.html"); myAndroidWebView.addJavascriptInterface(WebAppInterface(this), "AndroidApp"); } public fun testMessage(param: String){ println("Interface call-2") myAndroidWebView.post(Runnable { val str = "xxxXXXXXXXXXXXXXx $param" myAndroidWebView.loadUrl("javascript:Application.UserInterface.sample('$str')") }) println("Interface call-3") } }Ahora quiero enviar un mensaje a la aplicación de Android a JS y viceversa. Tengo un botón en HTML y activando la función.
public fun showToast(toast: String) {} Desde la vista HTML usando, AndroidApp.showToast("hello"); Lo cual funciona bien y recibo una llamada de JS a la función de interfaz de Android showToast()
Ahora, a pedido de JS, quiero obtener algunos valores de Android y enviarlos también a JS. Tengo una interfaz, en el botón de activación de HTML recibo una llamada en la siguiente función de interfaz. Y al intentar llamar a un método en MainActivity , public fun testMessage(param: String){} se activa con éxito.
Problema: estoy tratando de enviar datos a JS usando,
myAndroidWebView.loadUrl("javascript:Application.UserInterface.sample('$str')")Aquí estoy recibiendo un error.
W/System.err: kotlin.UninitializedPropertyAccessException: lateinit property myAndroidWebView has not been initializedcomo lo soluciono. Gracias.
/** Instantiate the interface and set the context */ class WebAppInterface(private val mContext: Context) { var mainActivity:MainActivity = MainActivity(); /** Show a toast from the web page */ @JavascriptInterface public fun showToast(toast: String) { println("Interface call-1") mainActivity.testMessage(mContext,toast); } }lateinit property not initialized se lanza porque está intentando crear una instancia de MainActivity en WebInterface. var mainActivity:MainActivity = MainActivity();
El trabajo del sistema Android es crear y cargar sus actividades. Nunca debe intentar iniciar una actividad .
Aquí, una mejora aproximada de su código. Intenta adaptarlo a tus necesidades.
interface JsCommunicator { fun testMessage(param: String) } class WebAppInterface(private val communicator: JsCommunicator) { @JavascriptInterface fun showToast(toast: String) { communicator.testMessage(toast) } } class YourMainActivity : JsCommunicator { // ... private lateinit var myAndroidWebView: WebView override fun testMessage(param: String) { println("Interface call-2") myAndroidWebView.post(Runnable { val str = "xxxXXXXXXXXXXXXXx $param" myAndroidWebView.loadUrl("javascript:Application.UserInterface.sample('$str')") }) println("Interface call-3") } }You are accessing web-view without initialising it. call setWebviewDetails() first then testMessage() or you can make webview nullable like this private var myAndroidWebView: WebView? = null; also you need to call startActivity() to create Activity not by creating objects as this is framework class managed by Android System.