[英]Dagger2 injection not happening - injected field is turning out to be null
I am struggling with my first Dagger2 project.我正在为我的第一个 Dagger2 项目而苦苦挣扎。
I want to inject a Context into a singleton class.我想将上下文注入 singleton class。 Here is a minimal example (I have removed package names, imports and have not included layouts, values or manifest files).
这是一个最小的示例(我已删除 package 名称、导入并且未包含布局、值或清单文件)。 This code ideally should pick up the string
<string name="app_name">My Application</string>
.理想情况下,此代码应获取字符串
<string name="app_name">My Application</string>
。
MainApplication.java:主要应用。java:
public class MainApplication extends Application {
private MainComponent mComponent;
@Override
public void onCreate() {
super.onCreate();
mComponent = DaggerMainComponent.builder()
.mainModule(new MainModule(this))
.build();
getComponent().inject(this);
}
public MainComponent getComponent() {
return mComponent;
}
}
MainModule.java: MainModule.java:
@Module
public class MainModule {
private final MainApplication mApplication;
public MainModule(MainApplication application) {
this.mApplication = application;
}
@Provides
@Singleton
public Context getApplicationContext() {
return mApplication.getApplicationContext();
}
}
MainComponent.java: MainComponent.java:
@Singleton
@Component(modules = MainModule.class)
public interface MainComponent {
void inject(MainApplication application);
}
MainActivity.java: MainActivity.java:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tvAppName = findViewById(R.id.main_app_name);
tvAppName.setText(MainHelper.getInstance().getApplicationName());
}
}
MainHelper.java: MainHelper.java:
public class MainHelper {
private static final MainHelper INSTANCE = new MainHelper();
@Inject
Context mContext;
public static MainHelper getInstance() {
return INSTANCE;
}
public String getApplicationName() {
return mContext.getString(R.string.app_name);
}
}
What actually happens is that I get this exception upon app launch itself:实际发生的是,我在应用程序启动时遇到了这个异常:
2019-11-14 18:46:47.561 9116-9116/com.example.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myapplication, PID: 9116
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myapplication/com.example.myapplication.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getString(int)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2830)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2909)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1606)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6592)
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:769)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getString(int)' on a null object reference
at com.example.myapplication.MainHelper.getApplicationName(MainHelper.java:21)
at com.example.myapplication.MainActivity.onCreate(MainActivity.java:16)
at android.app.Activity.performCreate(Activity.java:6984)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1235)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2783)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2909)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1606)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6592)
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:769)
Basically, the mContext
object in MainHelper
is null which to me means that the injection didn't work at all.基本上,
mContext
中的MainHelper
是 null 对我来说这意味着注入根本不起作用。 What is going wrong?出了什么问题? This code seems to adhere to pretty much all the tutorials out there.
这段代码似乎遵守了几乎所有的教程。
You're not injecting the Context
to your MainHelper
.您没有将
Context
注入MainHelper
。 I suggest you refactor your MainHelper
class to obtain the Context via Constructor injection (you should do this for all classes you own):我建议您重构您的
MainHelper
class 以通过构造函数注入获取上下文(您应该为您拥有的所有类执行此操作):
@Singleton
public class MainHelper {
private final Context context;
@Inject
public MainHelper(Context context) {
this.context = context;
}
}
The @Inject
annotation on the constructor should be enough so that Dagger knows to instantiate/create MainHelper
for you.构造函数上的
@Inject
注释应该足以让 Dagger 知道为您实例化/创建MainHelper
。 And then in order for this MainHelper
class to be injected to your MainActivity
, you first need to tell Dagger that you need to inject dependencies to your MainActivity
.然后为了将这个
MainHelper
class 注入到您的MainActivity
中,您首先需要告诉 Dagger 您需要将依赖项注入到您的MainActivity
中。 You already did something similar for your MainApplication
class:您已经为
MainApplication
class 做了类似的事情:
@Singleton
@Component(modules = MainModule.class)
public interface MainComponent {
void inject(MainApplication application);
void inject(MainActivity activity);
}
Then on your MainActivity
, you inject MainHelper
by calling the inject
method that Dagger generates for you:然后在您的
MainActivity
上,通过调用 Dagger 为您生成的inject
方法注入MainHelper
:
public class MainActivity extends AppCompatActivity {
@Inject
MainHelper helper;
@Override
protected void onCreate(Bundle savedInstanceState) {
((CustomApplication) getApplication()).getComponent().inject(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tvAppName = findViewById(R.id.main_app_name);
tvAppName.setText(helper.getApplicationName());
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.