简体   繁体   中英

Null Pointer Exception in Constructor Injection Dagger2 Android

I am trying to inject context in my Interactor class which is giving me a null pointer exception. I have used the MVP pattern and I am trying to get access to the context in my non-activity class. I am not really sure if this is the best technique used.

Module:

@Module
public class ContextModule {

private final Context context;

public ContextModule(Context context) {
    this.context = context;
}

@Singleton
@Provides
public Context getContext() {
    return this.context;
}

}

Component:

@Singleton
@Component(modules = {ContextModule.class})
public interface AppComponent {

void inject(MainActivity mainActivity);
}

App

public class App extends Application {

private AppComponent appComponent;

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

    appComponent = DaggerAppComponent.builder()
            .contextModule(new ContextModule(this))
            .build();
}

public AppComponent getAppComponent() {
    return appComponent;
}
}

MainActivity

public class MainActivity extends AppCompatActivity implements 
TaskContract.IMainView {

@Inject
MainInteractor mainInteractor;

private MainPresnter mainPresnter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

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

    mainPresnter = new MainPresnter(this);
}

@Override
public void getRandomNumber(int rNum) {
    Toast.makeText(this, "" + rNum, Toast.LENGTH_SHORT).show();
}

@Override
protected void onResume() {
    super.onResume();
    mainPresnter.fetchFromService();
}
}

Presenter

public class MainPresnter implements TaskContract.IMainPresenter, 
TaskContract.OnTaskCompletionResult {

private TaskContract.IMainView mainView;
private MainInteractor mainInteractor;

public MainPresnter(TaskContract.IMainView mainView) {
    this.mainView = mainView;
    mainInteractor = new MainInteractor(this);
}

@Override
public void fetchFromService() {
    mainInteractor.callService();
}

@Override
public void onSuccess(int rNum) {
    mainView.getRandomNumber(rNum);
}
}

Interactor

public class MainInteractor implements TaskContract.IMainInteractor {

private static final int JOB_ID = 100 ;
private Context context;

@Inject
public MainInteractor(Context context) {
    this.context = context;
}


public MainInteractor(TaskContract.OnTaskCompletionResult completionListener) 
{
    TaskService.setCompletionListener(completionListener);
}

@Override
public void callService() {
    JobInfo jobInfo = new JobInfo.Builder(JOB_ID,
            new ComponentName(context, TaskService.class))
            .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
            .setPeriodic(10000)
            .build();

    JobScheduler jobScheduler = (JobScheduler) 
    context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
    jobScheduler.schedule(jobInfo);
}
}

Gradle

implementation 'com.google.dagger:dagger-android:2.11'
annotationProcessor 'com.google.dagger:dagger-compiler:2.11'

You don't inject the Interactor within your Presenter - therefore it won't have a context.

You could probably restructure your Presenter to require the Interactor as a dependency - this would also mean you'd need to restructure how the completion listener is set.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM