Dagger2 注入未发生 - 注入字段结果为空
Dagger2 injection not happening - injected field is turning out to be null
我正在努力完成我的第一个 Dagger2 项目。
我想给单例注入一个上下文class。这是一个最小的例子(我已经删除了包名、导入并且没有包括布局、值或清单文件)。理想情况下,这段代码应该选择字符串 <string name="app_name">My Application</string>
.
MainApplication.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:
@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:
@Singleton
@Component(modules = MainModule.class)
public interface MainComponent {
void inject(MainApplication application);
}
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:
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);
}
}
实际发生的是我在应用程序本身启动时遇到此异常:
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)
基本上,MainHelper
中的 mContext
对象为 null,这对我来说意味着注入根本不起作用。出了什么问题?这段代码似乎遵循了几乎所有的教程。
您没有将 Context
注入您的 MainHelper
。我建议你重构你的 MainHelper
class 以通过构造函数注入获取上下文(你应该为你拥有的所有 class 执行此操作):
@Singleton
public class MainHelper {
private final Context context;
@Inject
public MainHelper(Context context) {
this.context = context;
}
}
构造函数上的 @Inject
注释应该足以让 Dagger 知道 instantiate/create MainHelper
为您服务。然后为了将此 MainHelper
class 注入到您的 MainActivity
,您首先需要告诉 Dagger 您需要将依赖项注入到您的 MainActivity
。您已经为 MainApplication
class:
做了类似的事情
@Singleton
@Component(modules = MainModule.class)
public interface MainComponent {
void inject(MainApplication application);
void inject(MainActivity activity);
}
然后在你的 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());
}
}
我正在努力完成我的第一个 Dagger2 项目。
我想给单例注入一个上下文class。这是一个最小的例子(我已经删除了包名、导入并且没有包括布局、值或清单文件)。理想情况下,这段代码应该选择字符串 <string name="app_name">My Application</string>
.
MainApplication.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:
@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:
@Singleton
@Component(modules = MainModule.class)
public interface MainComponent {
void inject(MainApplication application);
}
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:
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);
}
}
实际发生的是我在应用程序本身启动时遇到此异常:
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)
基本上,MainHelper
中的 mContext
对象为 null,这对我来说意味着注入根本不起作用。出了什么问题?这段代码似乎遵循了几乎所有的教程。
您没有将 Context
注入您的 MainHelper
。我建议你重构你的 MainHelper
class 以通过构造函数注入获取上下文(你应该为你拥有的所有 class 执行此操作):
@Singleton
public class MainHelper {
private final Context context;
@Inject
public MainHelper(Context context) {
this.context = context;
}
}
构造函数上的 @Inject
注释应该足以让 Dagger 知道 instantiate/create MainHelper
为您服务。然后为了将此 MainHelper
class 注入到您的 MainActivity
,您首先需要告诉 Dagger 您需要将依赖项注入到您的 MainActivity
。您已经为 MainApplication
class:
@Singleton
@Component(modules = MainModule.class)
public interface MainComponent {
void inject(MainApplication application);
void inject(MainActivity activity);
}
然后在你的 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());
}
}