I need something that can make my class nullable/optional because of the runtime errors that is happening on some devices.
Is this possible?
class MyFragment extends Fragment {
@Inject
var presenter: MyPresenter? = null
// Other codes here...
}
I wanted to use the presenter
as an option because SOME of the old Android devices especially are throwing this error (this is before I removed the lazyinit).
Code:
class MyFragment extends Fragment {
@Inject
lazyinit var presenter: MyPresenter? = null
// Other codes here...
override fun onDestroy() {
super.onDestroy()
presenter.somecode()
}
}
Error:
Fatal Exception: java.lang.RuntimeException: Unable to destroy activity {com.sample.MyActivity}: c.r: lateinit property presenter has not been initialized
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3497)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3515)
at android.app.ActivityThread.access$1400(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1249)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(NativeStart.java)
Caused by c.r: lateinit property presenter has not been initialized
at com.sample.MyFragment.onDestroy(SourceFile:459)
at android.support.v4.app.Fragment.performDestroy(SourceFile:2434)
at android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:1442)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(SourceFile:1528)
at android.support.v4.app.FragmentManagerImpl.moveToState(SourceFile:1595)
at android.support.v4.app.FragmentManagerImpl.dispatchDestroy(SourceFile:2951)
at android.support.v4.app.FragmentController.dispatchDestroy(SourceFile:271)
at android.support.v4.app.FragmentActivity.onDestroy(SourceFile:390)
at android.support.v7.app.AppCompatActivity.onDestroy(SourceFile:209)
at android.app.Activity.performDestroy(Activity.java:5403)
at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1117)
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3484)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3515)
at android.app.ActivityThread.access$1400(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1249)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(NativeStart.java)
Is there are way or workaround for this situation?
inject annotations. The reason for creating this library was to allow Kotlin common code to be dependency injected using dagger on the JVM. Dagger is a popular dependency injection library, used on Android and the JVM, which processes the javax. inject annotations to create a dependency graph during compile time.
Dagger cannot support private fields and still support code-generated adapters (to avoid reflection). The way systems like Guice support private fields is they change the access to the field reflectively before accessing them.
Component implementations that invoke @Provides methods that return null will throw a NullPointerException immediately thereafter. @Provides methods may opt into allowing null by annotating the method with any @Nullable annotation like javax.
The building block of kotlin-inject is a component which you declare with an @Component annotation on an abstract class. An implementation of this component will be generated for you. For external dependencies, you can declare a function or read-only property in the component to create an instance for a certain type.
I had the same problem and solved like this:
@Inject
@JvmField
var presenter: Presenter? = null
Hope it helps.
If you don't have Java code that needs to access the presenter
field you don't need to annotate it with @JvmField
. Instead, you can declare your field like so:
@set:Inject
var presenter: Presenter? = null
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With