-
Notifications
You must be signed in to change notification settings - Fork 842
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dagger2 - injecting presenter gives Caused by: java.lang.NullPointerException: Presenter returned from createPresenter() is null. Activity is ... #298
Comments
Hm, seems you have implemented it correctly. You have to do the dependency
injection in onCreate() BEFORE calling super.onCreate() which you did.
I think the problem is the following:
If you inject into your own presenter variable (I explicitly say own
variable, because Mosby internally already has a presenter variable too),
you also have to override getPresenter() and setPresenter() of
MvpActivity(). Please try to add this two methods.
j2emanue <[email protected]> schrieb am Fr., 22. Dez. 2017, 10:13:
… i was successfully using mosby2 for a long time now and changed to mosby3.
at runtime the presenter cannot be created. Tested on Oreo api 26 emulator
xxhdpi.
Here are the dependencies:
*implementation 'com.hannesdorfmann.mosby3:mvp:3.1.0' // Plain MVP
implementation 'com.hannesdorfmann.mosby3:viewstate:3.1.0' // MVP +
ViewState support*
If i do the following which is creating the presenter without dependency
injection there is no issue:
@nonnull <https://github.com/nonnull>
@OverRide <https://github.com/override>
public WelcomePresenter createPresenter() {
return new WelcomePresenter();
}
but the following gives a NPE when using dagger2 in android:
public class AuthenticationActivity extends MyappBaseMvpActivity<AuthenticationView, AuthenticationPresenter> implements AuthenticationView {
@Inject
AuthenticationPresenter presenter; //confirmed this value is not null
@OverRide
protected void onCreate(Bundle savedInstanceState) {
((MyappApplication) getApplicationContext()).getAppComponent().inject(this); //injecting presenter which works in Mosby2
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_authentication);
ButterKnife.bind(this);
presenter.loadScreen();
//blah blah
}
@nonnull
@OverRide
public AuthenticationPresenter createPresenter() {
return presenter; //confirmed through debugger this value is NOT null
}
}
Here is what i have tried: moving the " ((MyAppApplication)
getApplicationContext()).getAppComponent().inject(this);" call after the
super call and even after setnContentView. Same issues.
Here is the exact error i recieve :
FATAL EXCEPTION: main
Process: com.mobile.myapp.labs, PID: 2680
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.mobile.myapp.labs/com.mobile.myapp.ui.login.activities.AuthenticationActivity}:
java.lang.NullPointerException: Presenter returned from createPresenter()
is null. Activity is
***@***.***
at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
at
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.NullPointerException: Presenter returned from
createPresenter() is null. Activity is
***@***.***
at
com.hannesdorfmann.mosby3.mvp.delegate.ActivityMvpDelegateImpl.createViewIdAndCreatePresenter(ActivityMvpDelegateImpl.java:92)
at
com.hannesdorfmann.mosby3.mvp.delegate.ActivityMvpDelegateImpl.onCreate(ActivityMvpDelegateImpl.java:142)
at com.hannesdorfmann.mosby3.mvp.MvpActivity.onCreate(MvpActivity.java:42)
at
com.mobile.myapp.ui.base.MyappBaseMvpActivity.onCreate(MyappBaseMvpActivity.java:88)
at
com.mobile.myapp.ui.login.activities.AuthenticationActivity.onCreate(AuthenticationActivity.java:56)
at android.app.Activity.performCreate(Activity.java:6975)
at
android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
at
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
12-22 08:58:10.863 1811-1823/system_process E/memtrack: Couldn't load
memtrack module
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#298>, or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAjnriuP1IgcidmF-zwKwfHUeaxBEHASks5tC3LPgaJpZM4RK0GO>
.
|
ok. could you make it so that it accepts the presenter i am returning on onCreatePresenter ? I'll have to call this in all of our classes which is a huge task. Dagger2 does not work in base abstract classes. So each concrete class i'll have to override the getters/setters for the presenter. we never use to have to do this before , im wondering if you can change it to not do that ? |
Does getPresenter() and setPresenter() actually solves your problem? |
so here is what i did:
@nonnull
@OverRide
public LandingPagePresenter createPresenter() {
return presenter; //confirmed this is not null
}
@OverRide
public void setPresenter(@nonnull LandingPagePresenter presenter_notused) {
super.setPresenter(presenter); //confirmed neither presenter and presenter_notused are null (and they are the same )
}
i still unfortuantly, got the same error. which ill show below:
FATAL EXCEPTION: main
Process: com.mobile.myapp.labs, PID: 8977
java.lang.NullPointerException: Presenter returned from createPresenter() is null. Activity is com.mobile.myapp.ui.landing.LandingPageActivity@252836b
at com.hannesdorfmann.mosby3.mvp.delegate.FragmentMvpDelegateImpl.createViewIdAndCreatePresenter(FragmentMvpDelegateImpl.java:104)
at com.hannesdorfmann.mosby3.mvp.delegate.FragmentMvpDelegateImpl.onCreate(FragmentMvpDelegateImpl.java:268)
at com.hannesdorfmann.mosby3.mvp.MvpFragment.onCreate(MvpFragment.java:101)
at android.support.v4.app.Fragment.performCreate(Fragment.java:2246)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1377)
at android.support.v4.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java:1187)
at android.support.v4.app.FragmentTransition.calculateFragments(FragmentTransition.java:1070)
at android.support.v4.app.FragmentTransition.startTransitions(FragmentTransition.java:115)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2374)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2332)
at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:2209)
at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:649)
at android.support.v4.app.FragmentStatePagerAdapter.finishUpdate(FragmentStatePagerAdapter.java:167)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1238)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1086)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1616)
at android.view.View.measure(View.java:22002)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:958)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:685)
at android.view.View.measure(View.java:22002)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6580)
at android.support.design.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:719)
at android.support.design.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:791)
at android.view.View.measure(View.java:22002)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6580)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139)
at android.view.View.measure(View.java:22002)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6580)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1514)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:806)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:685)
at android.view.View.measure(View.java:22002)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6580)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:22002)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6580)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1514)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:806)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:685)
at android.view.View.measure(View.java:22002)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6580)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:721)
at android.view.View.measure(View.java:22002)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2410)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1498)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1751)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1386)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6733)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
12-22 11:30:01.985 8977-8977/com.mobile.myapp.labs E/AndroidRuntime: at android.view.Choreographer.doCallbacks(Choreographer.java:723)
at android.view.Choreographer.doFrame(Choreographer.java:658)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
|
If Presenter is the only thing you inject into your View, you can have the Component expose it so you can inject the Presenter itself in
Also, you don't need to include both mvp and viewstate Gradle dependency. The latter is sufficient. |
Yeah I definitely recommend to create the dependency graph in createPresenter() and have a component like this: @Component
interface MyApplicationComponent {
MyPresenter myPresenter();
} Rather than @Component
interface MyApplicationComponent {
void inject(MyActivity activityWherePresenterGetsInjected);
} Nevertheless, the way you would like to do it (inject presenter into activity) should also work if you override |
My presenter constructor takes arguments. Dagger builds it for me
Get Outlook for Android<https://aka.ms/ghei36>
…________________________________
From: James Shvarts <[email protected]>
Sent: Friday, December 22, 2017 6:51:05 PM
To: sockeqwe/mosby
Cc: j2emanue; Author
Subject: Re: [sockeqwe/mosby] Dagger2 - injecting presenter gives Caused by: java.lang.NullPointerException: Presenter returned from createPresenter() is null. Activity is ... (#298)
If Presenter is the only thing you inject into your View, you can have the object graph expose it and so you can inject the Presenter itself in createPresenter(). See example https://github.com/jshvarts/MosbyMVP/blob/master/conductor-dagger-sample/src/main/java/com/jshvarts/mosbymvp/searchrepos/SearchViewController.kt
Also, you don't need to include both mvp and viewstate Gradle dependency. The latter is sufficient.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub<#298 (comment)>, or mute the thread<https://github.com/notifications/unsubscribe-auth/AEuvOvgU1xjroSxzeC9V_nkiinKnsEehks5tC5epgaJpZM4RK0GO>.
|
Sure, that is not changed. dagger still creates the presenter instance with
all required dependencies (constructor parameters of presenter)
j2emanue <[email protected]> schrieb am Fr., 22. Dez. 2017, 13:14:
… My presenter constructor takes arguments. Dagger builds it for me
Get Outlook for Android<https://aka.ms/ghei36>
________________________________
From: James Shvarts ***@***.***>
Sent: Friday, December 22, 2017 6:51:05 PM
To: sockeqwe/mosby
Cc: j2emanue; Author
Subject: Re: [sockeqwe/mosby] Dagger2 - injecting presenter gives Caused
by: java.lang.NullPointerException: Presenter returned from
createPresenter() is null. Activity is ... (#298)
If Presenter is the only thing you inject into your View, you can have the
object graph expose it and so you can inject the Presenter itself in
createPresenter(). See example
https://github.com/jshvarts/MosbyMVP/blob/master/conductor-dagger-sample/src/main/java/com/jshvarts/mosbymvp/searchrepos/SearchViewController.kt
Also, you don't need to include both mvp and viewstate Gradle dependency.
The latter is sufficient.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub<
#298 (comment)>, or
mute the thread<
https://github.com/notifications/unsubscribe-auth/AEuvOvgU1xjroSxzeC9V_nkiinKnsEehks5tC5epgaJpZM4RK0GO
>.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#298 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAjnrv2ePK0138kuD4zNS0-0G16cC3FSks5tC50OgaJpZM4RK0GO>
.
|
If you look at my example above, you will see that my Presenter gets instantiated by Dagger and it takes parameters via constructor injection. |
I see no difference if I do this. I'm calling dagger inject before super.oncreate . Therefore my presenter already has a reference. I don't think createpresenter method is called before onCreate , right? I guess you guys changed the implementation a bit. How is exposing the method in the component bringing different results then annotating the presenter constructor with @Inject. I tried overriding set/getters as recommended but same issue. |
Is your source code available somewhere so that I can try to debug it? I think either you or we are misunderstanding something, so here is a full example implementation what @jshvarts and I are talking about is the following one: public class AuthenticationActivity extends MvpActivity<AuthenticationView, AuthenticationPresenter> implements AuthenticationView {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_authentication);
ButterKnife.bind(this);
presenter.loadScreen(); // presenter variable is a Mosby internal variable from MvpActivity
//blah blah
}
@Override
public AuthenticationPresenter createPresenter() {
return ((MyappApplication) getApplicationContext()).getAppComponent().authenticationPresenter();
}
} @Singleton
class AuthenticationPresenter extend MvpBasePresenter<AuthenticationView> {
@Inject
public AuthenticationPresenter(UserManager userManager) { // Some dependencies passed as constructor parameter
...
}
} @Module
class AppModule {
@Provides
@Singleton
public UserManager provideUserManager() {
...
}
} @Singleton
@Component(modules = {AppModule.class}
interface AppComponent {
AuthenticationPresenter authenticationPresenter();
} Please note that we are not manually instantiating
You are not removing The later is the recommended way for Mosby |
here is what i have done: My app component has the following declared: LandingPagePresenter landingPagePresenter(); and in the landingPageActivity i took out the @Inject annotation so now the presenter declartion looks like this: // @Inject here is the onCreate method: @OverRide here is the createpresenter override:
i also tried the following: @nonnull here is the constructor signature for the presenter:: @Inject i still get the same error:
in all cases above i have not overriden setPresenter or getPresenter. |
I believe all you need to do is to have this done:
Do not have any Dagger code in the |
I think I have to inject dagger dependencies from onCreate because I have other dependencies that need to be injected in not just a present. For example analytics manager etc.
Get Outlook for Android<https://aka.ms/ghei36>
…________________________________
From: James Shvarts <[email protected]>
Sent: Saturday, December 23, 2017 5:37:41 AM
To: sockeqwe/mosby
Cc: j2emanue; Author
Subject: Re: [sockeqwe/mosby] Dagger2 - injecting presenter gives Caused by: java.lang.NullPointerException: Presenter returned from createPresenter() is null. Activity is ... (#298)
I believe all you need to do is to have this done:
@OverRide
public LandingPagePresenter createPresenter() {
return ((MyApplication) getApplicationContext()).getAppComponent().landingPagePresenter();
}
Do not have any Dagger code in the onCreate() and do not declare LandingPagePresenter presenter in your Activity (View). Whenever you need to reference the Presenter in your Activity, just call presenter.foo()
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub<#298 (comment)>, or mute the thread<https://github.com/notifications/unsubscribe-auth/AEuvOkZVMrPt3SO03oTL-SsYYwuaD6e4ks5tDC81gaJpZM4RK0GO>.
|
That's why I asked in my first reply above if the Presenter was the only one dependency that needs to be injected. Something like this should work (I am converting it from Kotlin as I type): In your Dagger Component:
In your
|
jshvarts ,
i treied exactly as you put and i also tried it in another class just to make sure. its the same error. i have the code exactly how you wrote it. lets take a look more in depth at my code: here is my activity:
and here is the BaseActivity class definition:
and here is BaseMvpView:
again the environment im running on is Oreo api 26 but i also tried it on api 23 emulator. for completeness below is my dagger2 component:
|
I have some time tomorrow after lunch. I will try to reproduce / debug your
issue.
j2emanue <[email protected]> schrieb am Sa., 23. Dez. 2017, 07:08:
… jshvarts ,
i assume that you meant myPresenter variable in the setter and not
this.presenter :
@OverRide
void setPresenter(LandingPagePresenter presenter) {
this.myPresenter = presenter
}
i treied exactly as you put and i also tried it in another class just to
make sure. its the same error. i have the code exactly how you wrote it.
lets take a look more in depth at my code:
here is my activity:
`public class LandingPageActivity extends BaseMvpActivity<LandingPageView,
LandingPagePresenter> implements LandingPageView {
@Inject
LandingPagePresenter presenter;
@Inject
ApplicationMode appMode;
@Inject
EventBus bus;
@OverRide
public void setPresenter(LandingPagePresenter presenter) {
this.presenter = presenter;
}
@nonnull
@OverRide
public LandingPagePresenter createPresenter() {
return this.presenter;
}
@OverRide
protected void onCreate(Bundle savedInstanceState) {
((MyApplication) getApplicationContext()).getAppComponent().inject(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_homepage);
ButterKnife.bind(this);
initView();
}
}`
and here is the BaseActivity class definition:
public abstract class BaseMvpActivity<V extends BaseMvpView, P extends MvpPresenter<V>>
extends MvpActivity<V, P> {........}
and here is BaseMvpView:
public interface BaseMvpView extends MvpView {
void ***@***.*** int e);
void showError(String msg);
//....blah blah
}
again the environment im running on is Oreo api 26 but i also tried it on
api 23 emulator.
with dependency: implementation
'com.hannesdorfmann.mosby3:viewstate:3.1.0'
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#298 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAjnrmfTkfCXaqou--sTvI1yd9pHVTSrks5tDJjsgaJpZM4RK0GO>
.
|
@j2emanue Hi! I have a @Subcomponent
public interface LoginComponent {
@Subcomponent.Builder
interface Builder {
LoginComponent build();
}
void inject(LoginFragment loginFragment);
// Important!
LoginPresenter getLoginPresenter();
} I have a separate class called public class Injection {
private Injection() {
}
private static AppComponent appComponent;
private static LoginComponent loginComponent;
public static void init(Application application) {
appComponent = DaggerAppComponent.builder()
.application(application)
.build();
}
public static LoginComponent inject(LoginFragment loginFragment) {
loginComponent = appComponent.loginComponentBuilder().build();
loginComponent.inject(loginFragment);
return loginComponent;
}
public static void clear(LoginFragment loginFragment) {
loginComponent = null;
}
} And here is how all this stuff is being used in class LoginFragment : MviFragment<LoginView, LoginPresenter>(), LoginView {
private lateinit var loginComponent: LoginComponent
override fun onCreate(savedInstanceState: Bundle?) {
loginComponent = Injection.inject(this)
super.onCreate(savedInstanceState)
}
// Other lifecycle methods
override fun createPresenter(): LoginPresenter = loginComponent.loginPresenter
} This way I can inject all my fragment's dependensies using members-injection (calling Using this method I get no runtime exceptions. Hope I helped! |
do you guys want to set up a phone call or screen share so we can fix this issue ? |
@j2emanue Did you fix this issue ? |
I've got the same issue. Using Dagger 2.16 and Mosby 3.1.0. |
I had no problems injecting the presenter then setting it manually to the Mosby's internal presenter @Inject lateinit var myPresenter: MyPresenter MyPresenter uses dagger's constructor injecting of course |
i was successfully using mosby2 for a long time now and changed to mosby3. at runtime the presenter cannot be created. Tested on Oreo api 26 emulator xxhdpi.
Here are the dependencies:
implementation 'com.hannesdorfmann.mosby3:mvp:3.1.0' // Plain MVP
implementation 'com.hannesdorfmann.mosby3:viewstate:3.1.0' // MVP + ViewState support
If i do the following which is creating the presenter without dependency injection there is no issue:
@nonnull
@OverRide
public WelcomePresenter createPresenter() {
return new WelcomePresenter();
}
but the following gives a NPE when using dagger2 in android:
Here is what i have tried: moving the " ((MyAppApplication) getApplicationContext()).getAppComponent().inject(this);" call after the super call and even after setnContentView. Same issues.
Here is the exact error i recieve :
The text was updated successfully, but these errors were encountered: