0
In a project that has the Activity, Presenter and a Model, the Activity has the Presenter and the Presenter has a Model. When I do @Inject in the Presenter to instantiate the Model it is never instantiated.
FATAL EXCEPTION: main Process: fipedaggerrxjava, PID: 22258 java.lang.Nullpointerexception: Attempt to invoke interface method 'void fipedaggerrxjava.mvp.Selectmarcacontractmvp$Model.getMarcas(java.lang.String)' on a null Object Reference at fipedaggerrxjava.module.brand.MarcaPresenter.initData(Marcapresenter.java:35) at fipedaggerrxjava.module.marca.Marcaactivity$1.onCheckedChanged(Marcaactivity.java:63)
I have checked in Debug and really the Model that is not being instantiated by Dagger but I can not understand why.
App
public class App extends Application implements HasActivityInjector{
@Inject
public DispatchingAndroidInjector<Activity> activityDispatchingAndroidInjector;
@Override
public void onCreate() {
super.onCreate();
DaggerAppComponent.builder().build().inject(App.this);
}
@Override
public AndroidInjector<Activity> activityInjector() {
return activityDispatchingAndroidInjector;
}
}
Activitybuilder
@Module
public abstract class ActivityBuilder {
@Binds
@IntoMap
@ActivityKey(MarcaActivity.class)
abstract AndroidInjector.Factory<? extends Activity> bindMarcaActivity (MarcaComponent.Builder builder);
}
Appcomponent
@Component(modules = {ActivityBuilder.class, AndroidInjectionModule.class, AppModule.class})
@Singleton
public interface AppComponent {
void inject(App app);
}
Appmodule
@Module(subcomponents = MarcaComponent.class)
public class AppModule {
@Provides
@Singleton
@Named("URL_MARCA")
String provideStringURLBase(){
return "https://fipe.parallelum.com.br/api/v1/";
}
@Provides
@Singleton
Context provideContext(App app){
return app;
}
@Provides
@Singleton
Gson provideGsonRepositorie(){
return new GsonBuilder()
.create();
}
@Singleton
@Provides
OkHttpClient provideOkHttpCliente1(){
return new OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.build();
}
@Singleton
@Provides
RxJavaCallAdapterFactory provideRxJavaCallAdapterFactory(){
return RxJavaCallAdapterFactory.create();
}
@Provides
@Singleton
Retrofit provideRetrofit(OkHttpClient okHttpClient, Gson gson, RxJavaCallAdapterFactory rxAdapter, @Named("URL_MARCA") String stringBaseURL){
return new Retrofit.Builder()
.baseUrl(stringBaseURL)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(rxAdapter)
.client(okHttpClient)
.build();
}
}
Marcacomponent
@Subcomponent(modules = MarcaModule.class)
@PerMarca
public interface MarcaComponent extends AndroidInjector<MarcaActivity>{
@Subcomponent.Builder
abstract class Builder extends AndroidInjector.Builder<MarcaActivity> {}
}
Marcamodule
@Module
public class MarcaModule{
@Provides
@PerMarca
APIFIPE provideAPIFIPE(Retrofit retrofit){
return retrofit.create(APIFIPE.class);
}
@Provides
@PerMarca
View provideViewMarca(MarcaActivity activity){
return activity;
}
@Provides
@PerMarca
Presenter providePresenterMarca(){
return new MarcaPresenter();
}
@Provides
@PerMarca
Model provideModelMarca(){
return new MarcaModel();
}
}
Adaptermarca
public class AdapterMarca extends BaseAdapter {
private List<Marca> mListMarca;
@Inject
public Context mContext;
public AdapterMarca(List<Marca> listMarca){
this.mListMarca = listMarca;
}
@Override
public int getCount() {
return mListMarca.size();
}
@Override
public Object getItem(int position) {
return mListMarca.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = LayoutInflater.from(mContext).inflate(R.layout.layout_list_item, parent, false);
TextView tvNome = view.findViewById(R.id.tv_marca);
tvNome.setText(mListMarca.get(position).getName().toString());
return view;
}
public void addListMarca(List<Marca> marcaList){
mListMarca.clear();
mListMarca.addAll(marcaList);
notifyDataSetChanged();
}
}
Marcaactivity
public class MarcaActivity extends BaseActivity implements HasActivityInjector, View {
private RadioGroup radioGroupMarca;
private String tipoSelect = "";
private List<Marca> mListMarca;
private AdapterMarca mAdapterMarca;
private ListView listViewMarca;
@Inject
public Presenter mMarcaPresenter;
@Inject
protected DispatchingAndroidInjector<Activity> activityDispatchingAndroidInjector;
@Override
protected void onCreate(Bundle savedInstanceState) {
AndroidInjection.inject(MarcaActivity.this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listViewMarca = findViewById(R.id.lv_marca);
radioGroupMarca = findViewById(R.id.rg_tipo);
radioGroupMarca.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
int id = group.getCheckedRadioButtonId();
switch (id){
case R.id.rb_carros : tipoSelect = "carros";
mMarcaPresenter.initData(tipoSelect);
break;
case R.id.rb_motos : tipoSelect = "motos";
mMarcaPresenter.initData(tipoSelect);
break;
case R.id.rb_caminhoes : tipoSelect = "caminhoes";
mMarcaPresenter.initData(tipoSelect);
break;
}
}
});
}
@Override
public AndroidInjector<Activity> activityInjector() {
return activityDispatchingAndroidInjector;
}
@Override
public void onMarcaLoader(List<Marca> listMarcas) {
if(mListMarca==null && listMarcas!=null){
initListView();
}
if(mAdapterMarca!=null){
mListMarca.clear();
mListMarca = listMarcas;
mAdapterMarca.addListMarca(mListMarca);
}
}
private void initListView(){
mAdapterMarca = new AdapterMarca(mListMarca);
listViewMarca.setAdapter(mAdapterMarca);
}
}
Marcapresenter
@PerMarca
public class MarcaPresenter implements Presenter {
@Inject
View mMarcaView;
@Inject
Model mMarcaModel;
@Inject
public MarcaPresenter(){
}
@Override
public void initData(String tipoMarca) {
mMarcaModel.getMarcas(tipoMarca);
}
@Override
public void getMarcas(List<Marca> listMarcas) {
mMarcaView.onMarcaLoader(listMarcas);
}
@Override
public void onShowDialog(String title, String msg) {
mMarcaView.onShowDialog(title, msg);
}
@Override
public void onHideShowDialog() {
mMarcaView.onHideShowDialog();
}
@Override
public void onShowToast(String s) {
mMarcaView.onShowToast(s);
}
}
Marcamodel
@PerMarca
public class MarcaModel implements Model {
@Inject
APIFIPE mApiFIPE;
@Inject
Presenter mMarcaPresenter;
@Inject
public MarcaModel(){
}
@Override
public void getMarcas(String tipoVeiculo) {
final List<Marca> marcaList = new ArrayList<>();
Observable<List<Marca>> observable = mApiFIPE.getRepositories(tipoVeiculo);
observable.subscribe(new Observer<List<Marca>>() {
@Override
public void onCompleted() {
mMarcaPresenter.getMarcas(marcaList);
}
@Override
public void onError(Throwable e) {
mMarcaPresenter.onShowDialog("Erro", "Falha ao carregar lista de marcas");
}
@Override
public void onNext(List<Marca> marcas) {
marcaList.addAll(marcas);
}
});
}
}
"Let Dagger automatically inject your Presenter and Model from the dependency graph, meaning you don’t need to instantiate them within the module." But how would I do that? And this question of having Class A that has B and B that has C. Class B should be able to instantiate @Inject Class C normally or I have something special to do?
– Hugo
If B is injected by Dagger and depends on C, then C will be injected as well, provided C has the annotation
@Inject
.– Caique Jhones
I have tried several ways and I can’t get the model to receive an object from Degger with @Inject. Always from Nullpointerexception. Caique suggested above not to instantiate in Module but to let Dagger instantiate automatically, but how do I do this?
– Hugo