我正在使用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);
}
有谁知道如何解决此错误? 谢谢!
答案 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);