Home > Net >  kotlin.UninitializedPropertyAccessException: lateinit property WebView has not been initialized
kotlin.UninitializedPropertyAccessException: lateinit property WebView has not been initialized

Time:06-23

I created an android app and loading an html file on android webView. Which is loaded successfully and working fine.

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")
    }
}

Now I want to send message to Android app to JS and vice versa. I have a button in HTML and triggeting the function

public fun showToast(toast: String) {}

From HTML view by using, AndroidApp.showToast("hello"); Which is working fine and I am getting call from JS to Android interface function showToast()

Now on request from the JS I want to get some values from Android and send back to JS as well. I have an interface, on trigger button from HTML I am getting call on the below interface function. And trying to call a method in the MainActivity, public fun testMessage(param: String){} is triggered succssfully.

Issue: I am trying to send data to JS by using,

myAndroidWebView.loadUrl("javascript:Application.UserInterface.sample('$str')")

Here I am getting error.

W/System.err: kotlin.UninitializedPropertyAccessException: lateinit property myAndroidWebView has not been initialized

How do I resolve it. Thanks.

    /** 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);
    }
}

CodePudding user response:

lateinit property not initialized exception is thrown because you are trying to create an instance of MainActivity in WebInterface. var mainActivity:MainActivity = MainActivity();

It is Android system's job to create and load your activities. You should never try to initiate an activity.

Here, a rough improvement of your code. Try to adapt it to your needs.

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")
  }
}

CodePudding user response:

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.
  • Related