Kotlin null pointer exception when trying to get context from Registar in Flutter
In getContext
you have registrar!!
. And registrar
is a nullable field which you initialize to null
and can only set in a method which you never call. Note that fun MychartPlugin
isn't a constructor, you'd call it as e.g.
val plugin = MychartPlugin()
plugin.MychartPlugin(registrar)
But it doesn't seem like there is any reason to make registrar
nullable or mutable in the first place. You can change to
class MychartPlugin(private val registrar: Registrar): ...
and
fun registerWith(registrar: Registrar) {
val channel = MethodChannel(registrar.messenger(), "mychart_plugin")
channel.setMethodCallHandler(MychartPlugin(registrar))
}
Derek Hannah
Updated on December 10, 2022Comments
-
Derek Hannah over 1 year
I'm trying to create a Flutter Plugin that uses a native Android sdk
I'm able to compile the .aar libraries of the sdk and use them in the project but the sdk requires me to get the context of the main activity
here is the error im getting
E/MethodChannel#mychart_plugin(16277): Failed to handle method call E/MethodChannel#mychart_plugin(16277): kotlin.KotlinNullPointerException E/MethodChannel#mychart_plugin(16277): at org.ccf.flutter.plugin.mychart_plugin.MychartPlugin.getContext(MychartPlugin.kt:79) E/MethodChannel#mychart_plugin(16277): at epic.mychart.android.library.api.authentication.WPAPIAuthentication$1.getContext(WPAPIAuthentication.java:564) E/MethodChannel#mychart_plugin(16277): at epic.mychart.android.library.prelogin.AuthenticationService.libraryLogin(AuthenticationService.java:461) E/MethodChannel#mychart_plugin(16277): at epic.mychart.android.library.api.authentication.WPAPIAuthentication.login(WPAPIAuthentication.java:411) E/MethodChannel#mychart_plugin(16277): at org.ccf.flutter.plugin.mychart_plugin.MychartPlugin.onMethodCall(MychartPlugin.kt:42) E/MethodChannel#mychart_plugin(16277): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:201) E/MethodChannel#mychart_plugin(16277): at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:88) E/MethodChannel#mychart_plugin(16277): at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:219) E/MethodChannel#mychart_plugin(16277): at android.os.MessageQueue.nativePollOnce(Native Method) E/MethodChannel#mychart_plugin(16277): at android.os.MessageQueue.next(MessageQueue.java:325) E/MethodChannel#mychart_plugin(16277): at android.os.Looper.loop(Looper.java:142) E/MethodChannel#mychart_plugin(16277): at android.app.ActivityThread.main(ActivityThread.java:6541) E/MethodChannel#mychart_plugin(16277): at java.lang.reflect.Method.invoke(Native Method) E/MethodChannel#mychart_plugin(16277): at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) E/MethodChannel#mychart_plugin(16277): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
here is my code for getting the context
class MychartPlugin: MethodCallHandler, WPAPIAuthentication.IWPOnLoginListener { private var registrar: PluginRegistry.Registrar? = null private val LOGIN_REQUEST_CODE = 9876 fun MychartPlugin(registrar: PluginRegistry.Registrar) { this.registrar = registrar } companion object { @JvmStatic fun registerWith(registrar: Registrar) { val channel = MethodChannel(registrar.messenger(), "mychart_plugin") channel.setMethodCallHandler(MychartPlugin()) } } override fun onMethodCall(call: MethodCall, result: Result) { if (call.method == "getPlatformVersion") { result.success("Android ${android.os.Build.VERSION.RELEASE}") } else if (call.method == "MyChartSdkLogin") { WPAPIAuthentication.login(this, "TURKJ123", "TurkJ123", LOGIN_REQUEST_CODE) result.success("called MyChartSdkLogin") } else { result.notImplemented() } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) { // super.onActivityResult(requestCode, resultCode, data) if (requestCode == LOGIN_REQUEST_CODE) { if (resultCode == Activity.RESULT_OK) { // login successful Log.i("LoginFragment", "OK") } else { // login failed val result = WPAPIAuthentication.getLoginResult(data) Log.i("LoginFragment", result.toString()) val errorMessage = result.getErrorMessage(getContext()) if (!errorMessage.isEmpty()) { Toast.makeText(getContext(), errorMessage, Toast.LENGTH_LONG).show() } } } } override fun startActivityForResult(p0: Intent, p1: Int) { // super.startActivityForResult(p0, p1) } override fun getSupportFragmentManager(): FragmentManager { val act = registrar!!.activity() as FragmentActivity return act.getSupportFragmentManager() } override fun getContext(): Context { val cxt = registrar!!.context() return cxt } }
notice the override getContext() method that im overriding from the sdk, I think this context call to the registar is where my KotlinNullPointerException is coming from
-
Derek Hannah about 5 yearsthat was it thanks, I'm just getting back into Kotlin so im rusty haha