【问题标题】:I getting the following error using Dagger 2, Retrofit2 and AndroidAnnotations使用 Dagger 2、Retrofit2 和 AndroidAnnotations 时出现以下错误
【发布时间】:2017-08-17 16:21:57
【问题描述】:

我正在使用 Dagger 2(DI)、Retrofit2 和 AndroidAnnotations 创建一个 MVP(模型视图演示器)项目。但是在Activity.class的main函数里面注入这个组件时:

((App) getApplication()).getNetComponent().inject(this);

我收到以下错误:

java.lang.NullPointerException: Cannot return null from a non-@Nullable 
@Provides method

在下面找到我的代码: MainActivity.java:

@EActivity(R.layout.activity_main_view)
public class MainViewActivity extends AppCompatActivity implements SampleMainView {

  @Inject
  SampleMainPresenter sampleMainPresenter;

  @AfterViews
  void setupView(){
    ((App) getApplication()).getNetComponent().inject(this);
  }

}

App.java:

public class App extends Application {
  private NetComponent mNetComponent;

  @Override
  public void onCreate() {
    super.onCreate();

    mNetComponent = DaggerNetComponent.builder()
            .appModule(new AppModule(this))
            .netModule(new NetModule("http://www.bancaderiesgo.com/proyectos_admon/clases/"))
            .sampleMainPresenterModule(new SampleMainPresenterModule())
            .build();

  }

  public NetComponent getNetComponent() {
    return mNetComponent;
  }

}

AppModule.java:

@Module
public class AppModule {

  Application mApplication;

  public AppModule(Application application){
    this.mApplication = application;
  }

  @Provides
  @Singleton
  Application provideApplication(){
    return mApplication;
  }

}

NetModule.java:

 @Module
 public class NetModule {

  String mBaseUrl;

  public NetModule(String BaseUrl){
    this.mBaseUrl = BaseUrl;
  }

  @Provides
  @Singleton
  Cache provideHttpCache(Application application){
    int cacheSize = 10 * 1024 * 1024;
    Cache cache = new Cache(application.getCacheDir(), cacheSize);
    return  cache;
  }

  @Provides
  @Singleton
  Gson provideGson(){
    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.setFieldNamingPolicy(
         FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
    return gsonBuilder.create();
  }

  @Provides
  @Singleton
  OkHttpClient provideOkHttpClient(Cache cache){
    OkHttpClient.Builder client = new OkHttpClient.Builder();
    client.cache(cache);
    return client.build();
  }

  @Provides
  @Singleton
  Retrofit provideRetrofit(Gson gson, OkHttpClient okHttpClient){
    return new Retrofit.Builder()
            .addConverterFactory(GsonConverterFactory.create(gson))
            .baseUrl(mBaseUrl)
            .client(okHttpClient)
            .build();
  }

}

SampleMainPresenterModule.class

   @Module
   public class SampleMainPresenterModule {

      SampleMainView view;
      SampleMainInteractor sampleMainInteractor;

      @Provides
      @Singleton
      SampleMainView providesSampleMainView(){
        return view;
      }

      @Provides
      @Singleton
      SampleMainInteractor providesSampleInteractor(){
        return sampleMainInteractor;
      }

    }

SampleMainView.class

    public interface SampleMainView {

       void showMessage(String message);

       void showError(String error);

       void result(String msg);

   }

SampleMainInteractor.java

   public interface SampleMainInteractor {

      interface LoadListener {
        void onLoaded(List<String> items);
      }

      void loadItems(LoadListener listener);

    }

有谁知道如何解决这个错误? 谢谢!

【问题讨论】:

  • 这正是错误状态,您的@Provides 注释方法之一返回null。您没有包含堆栈跟踪,所以我们不知道在哪里或为什么。
  • @DavidMedenjak 抱歉,我错过了这段代码“SampleMainPresenterModule.class”
  • 现在你应该看看那个类。是viewnull,还是你在某个地方初始化它? sampleMainInteractor 呢?您是否在某处为其中任何一个赋值?
  • @DavidMedenjak 我编辑了我的代码并添加了另一个片段。

标签: java android retrofit2 dagger-2 android-annotations


【解决方案1】:

问题出在你的MainPresenterModule:

@Module
public class SampleMainPresenterModule {

   SampleMainView view;
   SampleMainInteractor sampleMainInteractor;

   @Provides
   @Singleton
   SampleMainView providesSampleMainView(){
     return view; //null pointer here
   }

   @Provides
   @Singleton
   SampleMainInteractor providesSampleInteractor(){
     return sampleMainInteractor; //null pointer here
   }
}

想想当 Dagger 2 在这种情况下尝试连接你的依赖关系图时会发生什么。你是说“SampleMainView 应该从这个模块中的view 字段提供”但view 字段永远不会初始化。

Presenter 的模块通常需要构造函数来传递视图。像这样的:

@Module
public class SampleMainPresenterModule {

   SampleMainView view;
   SampleMainInteractor sampleMainInteractor;

   SampleMainPresenterModule(SampleMainView view, SampleMainInteractor interactor) {
       this.view = view;
       this.interactor = interactor;
   }

   @Provides
   @Singleton
   SampleMainView providesSampleMainView(){
     return view; 
   }

   @Provides
   @Singleton
   SampleMainInteractor providesSampleInteractor(){
     return sampleMainInteractor;
   }
}

然后是在哪里初始化MainPresenterModule的问题。您当前正在 Application 子类中对其进行初始化。

这可能不是正确的方法 - 您想使用子组件或依赖组件并在 Activity 或 Fragment 中使用演示器模块配置组件。您正在遵循的教程或书籍应该解释这一点。

如果您使用依赖组件(我认为这些更容易开始),那么您可以在 Activity 中执行以下操作:

void onCreate(Bundle savedInstanceState) { 
   super.onCreate(savedInstanceState);
   DaggerMainComponent.builder()
       .netComponent(((App)getApplication())
       .mainPresenterModule(new SampleMainPresenterModule(this, this))
       .build() 
       .inject(this);

【讨论】:

  • 嗨!非常感谢,它成功了。你知道如何为数据源调用 Retrofit 2 吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多