Dagger2非空的@Provides方法。

10

我刚开始在我的项目中使用Dagger。我已经创建了以下这些模块:

@Module
public class FirebaseModule {

@Provides @Singleton
public FirebaseUser provideCurrentUser(){
    return FirebaseAuth.getInstance().getCurrentUser();
}

@Provides @Singleton
public DatabaseReference provideDatabaseReference(){
    return FirebaseDatabase.getInstance().getReference();
}

@Provides @Singleton
public FirebaseAuth provideFirebaseAuth(){
    return FirebaseAuth.getInstance();
}
}

而且这个:

@Module
public class AppModule
{
private HappyParkApp app;

public AppModule(HappyParkApp app) {
    this.app = app;
}

@Provides
public HappyParkApp providesApp()
{
return this.app;
}

@Provides
public Context getAppContext(){
    return this.app;
}
}

我也制作了这个组件:

@Singleton
@Component(modules = {AppModule.class,
                      FirebaseModule.class})
public interface AppComponent {

    void inject(MainActivity activity);
}

这是应用程序中实现的appComponent:

public class HappyParkApp extends Application {

private AppComponent appComponent;
private static HappyParkApp instance = new HappyParkApp();
@Override
public void onCreate() {
    super.onCreate();
    createAppComponent();
}

public static HappyParkApp getInstance() {
    return instance;
}

public AppComponent createAppComponent() {
 if(appComponent == null){
     appComponent = DaggerAppComponent.builder()
             .appModule(new AppModule(this))
             .firebaseModule(new FirebaseModule()).build();
 }

 return appComponent;
}
所以我已经试图在MainActivity的onCreate()方法中实现这个:

}

HappyParkApp.getInstance().createAppComponent().inject(this);

还有这个:

 @Inject
FirebaseUser user;

@Inject
DatabaseReference reference;

@Inject
FirebaseAuth mAuth;

但是我遇到了这个错误:

 Caused by: java.lang.NullPointerException: Cannot return null from a non-@Nullable @Provides method
在这一行:
 HappyParkApp.getInstance().createAppComponent().inject(this);

我不知道如何修复它:是什么错误?这是错误的注入吗?

谢谢你

2个回答

16

不能从非-@Nullable @Provides方法返回null

你试图从一个没有标记为@Nullable的提供者方法中提供null

请查看getCurrentUser()

返回当前已登录的Firebase用户,如果没有则返回null。

因此,在没有已登录用户的情况下,这将是null,使以下内容无效...

@Provides @Singleton
public FirebaseUser provideCurrentUser(){
  return FirebaseAuth.getInstance().getCurrentUser(); // could be null!
}

因此,要解决这个问题,您有两个选项:

  • 提供FirebaseAuth并在应用程序代码中获取用户,或
  • 将提供者标记为@Nullable

哪种方法更好取决于您的设置,但由于您将用户放置在@Singleton范围的组件中,我建议提供用户,因为它可能会在“Singleton”的生命周期内发生变化。

可以将其移到其他范围(例如@UserScope@PerUser)中,或者只需在需要时使用FirebaseAuth.getCurrentUser()获取用户。当然您仍然可以提供FirebaseAuth

此外,请查阅此处关于空值的说明


1
谢谢,你帮助我理解了这个概念 ;) - ste9206
4
我标记了那些可能提供空值的方法为@Nullable,以及我提供该值的地方,但是无论如何我仍然收到这样的错误信息:“...不可为空,但是由@Provides @android.support.annotation.Nullable提供”。我做错了什么? - Sirop4ik

6

如果您在提供方法中使用@Nullable注释,并忘记在想要使用该对象时使用@Nullable,那么dagger将会抛出一个错误(is not nullable but is being provided by @Provides @android.support.annotation.Nullable

因此,如果您提供了可空对象,请确保为每个使用该对象作为参数的方法添加@Nullable

例如:

@Nullable
@Provides
static Object provideHomePost(MainActivity activity){
    return activity.getObject();
}
@Provides
static Presenter providePresenterFactory(@Nullable HomePost post) {
    return new CommentPresenterImpl(post);
}

1
非常好的答案,谢谢。在我的情况下,我忘记用@Inject @Nullable User user注释实际被注入的对象了。 - MoGa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接