Android Dagger2 依赖注入
Android Dagger2 Dependency Injection
我是 Dagger2 的新手,我正在尝试在我的应用程序中使用依赖注入。
我正在使用共享首选项,并认为使用依赖注入而不是每次我需要使用它时都获取共享首选项的实例会更有帮助。
当我在 Activity 和 Fragments 上使用它时它工作正常,但当我尝试在服务或 intentservice 上使用它时它不起作用。
这是我的代码:
AppModule:
@Module
public class AppModule
{
public final ApplicationClass application;
public AppModule(ApplicationClass application)
{
this.application = application;
}
@Provides @Singleton
Context providesApplicationContext()
{
return this.application;
}
@Provides @Singleton
SharedPreferences providesSharedPreferences()
{
return application.getSharedPreferences(Constants.FILE_NAME,Context.MODE_PRIVATE);
}
}
AppComponent
@Singleton @Component(modules = {AppModule.class})
public interface AppComponent
{
void inject (ApplicationClass applicationClass);
void inject (IntentService intentService);
void inject (Service service);
}
ApplicationClass
public class ApplicationClass extends Application
{
AppComponent appComponent;
@Override
public void onCreate()
{
super.onCreate();
Thread.setDefaultUncaughtExceptionHandler(new
Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
onUncaughtException(t, e);
}
});
appComponent = DaggerAppComponent
.builder()
.appModule(new AppModule(this))
.build();
appComponent.inject(this);
}
public AppComponent getAppComponent()
{
return this.appComponent;
}
private void onUncaughtException(Thread t, Throwable e)
{
e.printStackTrace();
Intent crash= new Intent(getApplicationContext(),Crash.class);
about.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(crash);
}
}
所以我尝试在 IntentService 中注入共享首选项并且我使用了这些代码行
在我的服务 (intentservice)
的 onCreate 方法中
@Inject
SharedPreferences preferences;
@Override
public void onCreate()
{
super.onCreate();
((ApplicationClass)getApplication()).getAppComponent().inject(this);
}
但问题是,当我在 onHandleIntent
方法中使用此首选项变量时,应用程序崩溃,因为首选项为空。
那为什么不注入呢?
对于遇到此问题的任何人。
正如 Vadim Korzun 和 EpicPandaForce 在上面的评论中提到的,
我应该在注入方法中指定具体的class。
所以在我的例子中,我的 IntentService class 被命名为 GeofenceService
在 AppComponent 界面里面我应该写
void inject (GeofenceService service);
Service
也是一样
更新:
因此,对于拥有多个继承自 IntentService 的服务并希望避免为每个特定服务编写注入方法的人来说。
我建议执行以下步骤:
- 创建
BasicIntentService
扩展 IntentService
- 在你的
AppComponent
接口中添加以你BasicIntentService
为参数的注入方法。
- 在您的
BasicIntentSerive
中,您将有一个带有 Inject
注释的 protected SharedPrefrences
变量。
不过,在您的 BasicIntentService
中,在 onCreate
方法中您将调用这行代码
((ApplicationClass)getApplication()).getAppComponent().inject(this);
现在您创建的每个 IntentService
都将 扩展 BasicIntentService
并且您将能够使用 SharedPreferences
变量.
应用组件:
@Singleton @Component(modules = {AppModule.class})
public interface AppComponent
{
void inject (YourApplicationClass applicationClass);
void inject (BasicIntentService intentService);
}
BasicIntentService
public class BasicIntentService extends IntentService
{
@Inject
protected SharedPreferences sharedPreferences;
@Override
public void onCreate()
{
super.onCreate()
((YourApplicationClass)getApplication()).getAppComponenet().inject(this);
}
}
SomeIntentService
public class SomeIntentService extends BasicIntentService
{
@Override
public void onCreate()
{
super.onCreate();
}
-----------
@Override
protected void onHandleIntent(@Nullable Intent intent)
{
// some code
if (sharedPreferences.contains(someKey))
{
// some code
}
else
{
// some code
}
}
}
我是 Dagger2 的新手,我正在尝试在我的应用程序中使用依赖注入。 我正在使用共享首选项,并认为使用依赖注入而不是每次我需要使用它时都获取共享首选项的实例会更有帮助。 当我在 Activity 和 Fragments 上使用它时它工作正常,但当我尝试在服务或 intentservice 上使用它时它不起作用。
这是我的代码:
AppModule:
@Module
public class AppModule
{
public final ApplicationClass application;
public AppModule(ApplicationClass application)
{
this.application = application;
}
@Provides @Singleton
Context providesApplicationContext()
{
return this.application;
}
@Provides @Singleton
SharedPreferences providesSharedPreferences()
{
return application.getSharedPreferences(Constants.FILE_NAME,Context.MODE_PRIVATE);
}
}
AppComponent
@Singleton @Component(modules = {AppModule.class})
public interface AppComponent
{
void inject (ApplicationClass applicationClass);
void inject (IntentService intentService);
void inject (Service service);
}
ApplicationClass
public class ApplicationClass extends Application
{
AppComponent appComponent;
@Override
public void onCreate()
{
super.onCreate();
Thread.setDefaultUncaughtExceptionHandler(new
Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
onUncaughtException(t, e);
}
});
appComponent = DaggerAppComponent
.builder()
.appModule(new AppModule(this))
.build();
appComponent.inject(this);
}
public AppComponent getAppComponent()
{
return this.appComponent;
}
private void onUncaughtException(Thread t, Throwable e)
{
e.printStackTrace();
Intent crash= new Intent(getApplicationContext(),Crash.class);
about.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(crash);
}
}
所以我尝试在 IntentService 中注入共享首选项并且我使用了这些代码行 在我的服务 (intentservice)
的 onCreate 方法中@Inject
SharedPreferences preferences;
@Override
public void onCreate()
{
super.onCreate();
((ApplicationClass)getApplication()).getAppComponent().inject(this);
}
但问题是,当我在 onHandleIntent
方法中使用此首选项变量时,应用程序崩溃,因为首选项为空。
那为什么不注入呢?
对于遇到此问题的任何人。 正如 Vadim Korzun 和 EpicPandaForce 在上面的评论中提到的, 我应该在注入方法中指定具体的class。
所以在我的例子中,我的 IntentService class 被命名为 GeofenceService
在 AppComponent 界面里面我应该写
void inject (GeofenceService service);
Service
更新:
因此,对于拥有多个继承自 IntentService 的服务并希望避免为每个特定服务编写注入方法的人来说。 我建议执行以下步骤:
- 创建
BasicIntentService
扩展IntentService
- 在你的
AppComponent
接口中添加以你BasicIntentService
为参数的注入方法。 - 在您的
BasicIntentSerive
中,您将有一个带有Inject
注释的protected SharedPrefrences
变量。 不过,在您的
BasicIntentService
中,在onCreate
方法中您将调用这行代码((ApplicationClass)getApplication()).getAppComponent().inject(this);
现在您创建的每个
IntentService
都将 扩展BasicIntentService
并且您将能够使用SharedPreferences
变量.
应用组件:
@Singleton @Component(modules = {AppModule.class})
public interface AppComponent
{
void inject (YourApplicationClass applicationClass);
void inject (BasicIntentService intentService);
}
BasicIntentService
public class BasicIntentService extends IntentService
{
@Inject
protected SharedPreferences sharedPreferences;
@Override
public void onCreate()
{
super.onCreate()
((YourApplicationClass)getApplication()).getAppComponenet().inject(this);
}
}
SomeIntentService
public class SomeIntentService extends BasicIntentService
{
@Override
public void onCreate()
{
super.onCreate();
}
-----------
@Override
protected void onHandleIntent(@Nullable Intent intent)
{
// some code
if (sharedPreferences.contains(someKey))
{
// some code
}
else
{
// some code
}
}
}