我使用Dagger 2,Retrofit2和AndroidAnnotations得到以下错误

时间:2017-08-17 16:21:57

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

我正在使用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);

    }

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

1 个答案:

答案 0 :(得分: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字段从未初始化。

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

@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中的presenter模块配置组件。您正在学习的教程或书籍应该解释这一点。

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

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