Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin and Dagger: Can I use @Inject to an object still make it nullable/optional?

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?

like image 661
Paula Kristin Avatar asked Jun 01 '17 14:06

Paula Kristin


People also ask

What is @inject annotation in Kotlin?

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.

Can a dagger inject a private field?

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.

Can provides return null?

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.

How do you inject Kotlin?

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.


2 Answers

I had the same problem and solved like this:

@Inject
@JvmField
var presenter: Presenter? = null

Hope it helps.

like image 121
gmemario Avatar answered Sep 28 '22 17:09

gmemario


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
like image 40
hopia Avatar answered Sep 28 '22 17:09

hopia