在网上搜索了解此功能后,大多数主题或帖子都使用依赖注入Retrofit
或其他Android有用的库,但我有一些自定义类,我想用DI和我可以&# 39;完成它,例如我有一个简单的自定义类用于使用SharePreference
并且我使用它作为Singleton类
在我的代码中,我无法为SpApplication
类上的组件分配正确的Dagger,以便在活动或片段上使用它
public class SP {
private SharedPreferences preferences;
private Context context;
public SP(Context context) {
this.context = context;
}
private SharedPreferences getPrefs() {
return preferences = PreferenceManager.getDefaultSharedPreferences(context);
}
public String getString(SharedPrefsTypes propertyName) {
return getPrefs().getString(propertyName.toString(), "");
}
public int getInt(SharedPrefsTypes propertyName) {
return getPrefs().getInt(propertyName.toString(), 0);
}
...
public enum SharedPrefsTypes {
Login
}
}
现在我正在尝试使用DI:
AppModules类:
@Module
public class AppModules {
private Context context;
public AppModules(Context context) {
this.context = context;
}
@Provides
@Singleton
SP provideSharePreferences() {
SP sharePreference = new SP(context);
return sharePreference;
}
}
ApplicationComponent
上课:
@Component(modules = AppModules.class)
public interface ApplicationComponent {
void inject(ActivityMain activity);
}
SpApplication
上课:
public class SpApplication extends Application {
private static SpApplication self;
private ApplicationComponent component;
@Override
public void onCreate() {
super.onCreate();
self = this;
component = DaggerApplicationComponent.builder().build();
}
public static SpApplication get(Context context) {
return (SpApplication) context.getApplicationContext();
}
public static SpApplication getInstance() {
return self;
}
public ApplicationComponent getComponent() {
return component;
}
}
和我的ActivityMain
班级:
public class ActivityMain extends AppCompatActivity {
@Inject
SP sharePreference;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
((SpApplication) getApplication()).getComponent().inject(this);
sharePreference.setInt(SP.SharedPrefsTypes.Login, 0);
}
}
我收到此错误:
android.app.Application cannot be cast to com.pishguy.yendir.SpApplication
提前致谢
答案 0 :(得分:2)
我猜你试图注入ActivityMain
,但由于你没有提供它的来源,让我告诉你如何注入SpApplication
。然后只需将相关部分复制到Activity
。
我认为你需要改变的事情很少。
<强>模块:强>
您的AppModules
课程通常没问题,但我建议您改变使用Context
的方式 - 不要将其用作字段,而是将其注入其他任何字段服务。它看起来像这样:
@Module
public class AppModules {
private Context context;
public AppModules(Context context) {
this.context = context;
}
@Provides // this can be non-scoped because anyway the same instance is always returned
Context provideContext() {
return this.context;
}
@Provides
@Singleton
SP provideSharePreferences(Context context) {
return new SP(context); // use method-local Context
}
}
<强>组件:强>
考虑到这两点,ApplicationComponent
应如下所示:
@Singleton // injects @Singleton scoped services
@Component(modules = AppModules.class)
public interface ApplicationComponent {
void inject(SpApplication application); // SpApplication is DI client (injection target)
}
<强>客户端:强>
我改变了SpApplication
课程中的一些内容:
ApplicationComponent
的方式不正确get(Context)
和getInstance()
方法此外,由于我展示了如何注入SpApplication
,我还将添加注入逻辑(您应该将其复制到实际客户端)。
因此,SpApplication
(DI客户端)看起来应该类似于:
public class SpApplication extends Application {
@Inject SP sp; // the dependency that should be injected
private ApplicationComponent component;
@Override
public void onCreate() {
super.onCreate();
getComponent().inject(this); // this is when the actual injection takes place
}
public ApplicationComponent getComponent() {
if (component == null) {
// this is the way Dagger components should be instantiated
component = DaggerApplicationComponent.builder()
.appModules(new AppModules(this))
.build();
}
return component;
}
}
如果您执行上述更改,我倾向于相信您会没事。
顺便说一句,我最近完成了关于Dagger 2范围的blog post。如果你要认真对待依赖注入,你可能想检查它。