Сбой Dagger 2: «Не удается вернуть null из метода, отличного от @Nullable @Provides»

#java #android #android-studio #exception #dagger-2

#java #Android #android-studio #исключение #dagger-2

Вопрос:

Я не смог воссоздать его самостоятельно. Это сбой, который обнаружился в Crashlytics от Fabric.

Номер строки указывает на это: App.getApp().getApplicationComponent().inject(this);

Я не вижу, где я ошибаюсь.

‘App’ — это расширение класса Application, которое есть в манифесте и отлично работает на устройствах, на которых я тестирую. Это похоже на это:

 applicationComponent = DaggerApplicationComponent.builder()
            .appModule(new AppModule(this))
...
...
            .netModule(new NetModule())
            .build();
  

Фрагмент сбоя, о котором идет речь, имеет зависимость, отмеченную аннотацией @Inject .

Вот полная трассировка стека:

 Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfo{com....../com.....activities.MainActivity}: java.lang.NullPointerException: Cannot return null from a non-@Nullable @Provides method
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3254)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3350)
   at android.app.ActivityThread.access$1100(ActivityThread.java:222)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:158)
   at android.app.ActivityThread.main(ActivityThread.java:7229)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Caused by java.lang.NullPointerException: Cannot return null from a non-@Nullable @Provides method
   at dagger.internal.Preconditions.checkNotNull(Preconditions.java:48)
   at com.....di.modules....Module_Provides...Factory.get(...Module_Provides...Factory.java:30)
   at com......di.modules....Module_Provides...Factory.get(...Module_Provides...Factory.java:10)
   at dagger.internal.DoubleCheck.get(DoubleCheck.java:47)
   at com.....fragments.HomeFragment_MembersInjector.injectMembers(HomeFragment_MembersInjector.java:39)
   at com.....fragments.HomeFragment_MembersInjector.injectMembers(HomeFragment_MembersInjector.java:9)
   at com.....di.DaggerApplicationComponent.inject(DaggerApplicationComponent.java:217)
   at com.....fragments.HomeFragment.onCreate(HomeFragment.java:87)
   at android.support.v4.app.Fragment.performCreate(Fragment.java:2068)
   at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1055)
   at android.support.v4.app.BackStackRecord.setLastIn(BackStackRecord.java:838)
   at android.support.v4.app.BackStackRecord.calculateFragments(BackStackRecord.java:878)
   at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:719)
   at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1677)
   at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:388)
   at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:604)
   at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:178)
   at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1265)
   at android.app.Activity.performStart(Activity.java:6915)
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3217)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3350)
   at android.app.ActivityThread.access$1100(ActivityThread.java:222)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:158)
   at android.app.ActivityThread.main(ActivityThread.java:7229)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
  

Комментарии:

1. Итак, что это за вещь, которую вы пытаетесь внедрить, и есть null ?

2. @EpicPandaForce Я не знаю. Трассировка стека не указывает, и есть 2 зависимости, ни одна из которых не должна быть нулевой. Они оба поступают из базы данных Ormlite.

3. @EpicPandaForce Как мне сделать класс обнуляемым? Я попытался запустить его и пометить @Provides метод с помощью @Nullable , но он пожаловался и сказал, что класс должен быть обнуляемым. Я пометил его @Nullable , и это ничего не дало.

4. @EpicPandaForce по-прежнему получает этот сбой, где значения не должны быть нулевыми. Я собираюсь удалить Dagger 2.

5. Я этого не сделал. Я удалил Dagger 2, переписал свои классы, и он отлично работал без каких-либо сбоев.

Ответ №1:

Я только что исправил ту же проблему, вернув объект по умолчанию вместо null. Моя ошибка началась с того же сообщения Dagger. Я думал, что смогу справиться с null во введенном классе. Имеет большой смысл сделать все зависимости ненулевыми, поскольку они могут быть частью других зависимостей. Это очень фундаментально, но, конечно, при написании кода я об этом не подумал.

 @Provides
@Singleton
public FavCountry provideFavoriteCountry(RealmProvider realmProvider){

    FavCountry country = realmProvider.getRealm().where( FavCountry.class ).findFirst();

    //wait a minute, the table can be empty
    if( country == null ){
        country = new FavCountry("");
    }

    return country;
}