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.