gpt4 book ai didi

android - Dagger 2 创建单例实例

转载 作者:行者123 更新时间:2023-11-29 19:38:22 25 4
gpt4 key购买 nike

考虑我在 Presenter A 调用 Webservice 并在同一个 Presenter 保存响应数据的场景。我想在演示者 E 上使用相同的响应数据。但是我无法将响应对象传递给每个演示者 B、C、D。因此,我尝试将我的响应对象存储在带有 getter 和 setter 的单独的 Holder 类中。我使用 Dagger Inject 构造函数注释初始化了 Holder 类,并尝试在 Presenter E 上使用它。但是我得到的是 Empty 响应而不是我的 datas 。谁能建议我以最好的方式处理这种情况。提前致谢

最佳答案

您在使用 Dagger2 方面有很多基本问题,但我的时间有限,所以我暂时会回答有关 Mortar 的问题 - 我只能说在某些设备中,getSystemService()Application 中的调用比在 onCreate() 中的调用早,这意味着您应该像这样初始化根迫击炮作用域:

@Override
public Object getSystemService(String name) {
if(rootScope == null) {
rootScope = MortarScope.buildRootScope()
.withService(InjectorService.TAG, new InjectorService(this))
.build("Root");
}
if(rootScope.hasService(name)) { // if the additional "Context" service is within Mortar
return rootScope.getService(name);
}
return super.getSystemService(name); // otherwise return application level context system service
}

就个人而言,我在我的 onCreate()

中有这个
@Override
public void onCreate() {
super.onCreate();
Fabric.with(this, new Crashlytics());
realmHolder = new RealmHolder();
ApplicationHolder.INSTANCE.setApplication(this);
appConfig = new AppConfig(this);
InjectorService.obtain().inject(this); // <--- this one obtains component
initializeRealm();
}

在 InjectorService 中:

public static ApplicationComponent obtain() {
return ((InjectorService) MortarScope.getScope(ApplicationHolder.INSTANCE.getApplication())
.getService(TAG)).getComponent();
}

因此,在最坏的情况下,getSystemService() 会在启动时或创建单例 Dagger 组件时初始化我的 RootScope。

这个解决方案目前不是多进程友好的(因此 Firebase 崩溃报告会通过在 CustomApplication 中调用 onCreate() 两次来终止它)

编辑:注入(inject)器服务代码

public class InjectorService {
public static final String TAG = "InjectorService";

private ApplicationComponent applicationComponent; //dagger2 app level component

InjectorService(CustomApplication customApplication) {
AppContextModule appContextModule = new AppContextModule(customApplication);
RealmModule realmModule = new RealmModule();
applicationComponent = DaggerApplicationComponent.builder()
.appContextModule(appContextModule)
.realmModule(realmModule)
.build();
}

public ApplicationComponent getInjector() { //return the app component to inject `this` with it
return applicationComponent;
}

public static InjectorService get(Context context) {
//this is needed otherwise the compiler is whining. -_-
//noinspection ResourceType
return (InjectorService) context.getSystemService(TAG);
}

public static ApplicationComponent obtain() {
return ((InjectorService) MortarScope.getScope(ApplicationHolder.INSTANCE.getApplication())
.getService(TAG)).getInjector();
}
}

至于你最初的问题,这是因为你在构造函数中添加了 @Inject 注释,但没有在类本身上包含 @Singleton

@Singleton
public class Blah {
@Inject
public Blah() {
}
}

编辑:

我放假回家,所以初始错误是

Error:(40, 5) error: com.hari.daggerpoc.application.App.Component scoped with @com.hari.daggerpoc.frameworks.dagger.DaggerScope may not reference bindings with different scopes: @Singleton class com.hari.daggerpoc.cache.ResponseCache

App中引用了这个类:

@dagger.Component(modules = {Module.class})
@DaggerScope(Component.class)
public interface Component extends AppDependencies {

void inject(App app);
}

继承自该类:

@Module(includes = {Utils.class, ResponseCache.class})
public interface AppDependencies {

Utils utils();

ResponseCache responseCache();

}

...这完全不是一个模块,所以注释是不必要的,但是嘿。

无论如何,现在的问题是,虽然依赖是有范围的,但它来自不同的范围(我不知道没有使用单例范围),所以如果你改变 p>

@Singleton
public class ResponseCache {
@Inject
public ResponseCache(){
}

@DaggerScope(App.Component.class)
public class ResponseCache {

@Inject
public ResponseCache(){

}

然后如果在 ScreenA 中你改变了

    public Callback<WeatherResponse> configServiceCallback = new Callback<WeatherResponse>() {
@Override
public void onResponse(Call<WeatherResponse> call, Response<WeatherResponse> response) {
Log.d("ScreenA","Response data -->"+response.body().toString());
Flow.get(context).setHistory(History.single(new ScreenB()), Flow.Direction.FORWARD);
responseCache.setWeatherResponse(response.body());
}

    public Callback<WeatherResponse> configServiceCallback = new Callback<WeatherResponse>() {
@Override
public void onResponse(Call<WeatherResponse> call, Response<WeatherResponse> response) {
Log.d("ScreenA","Response data -->"+response.body().toString());
responseCache.setWeatherResponse(response.body());
Flow.get(context).setHistory(History.single(new ScreenB()), Flow.Direction.FORWARD);
}

然后它说

08-28 18:12:48.369 31253-31253/com.hari.daggerpoc D/ScreenA: Response data -->WeatherResponse{endpoint=Endpoint{url='http://www.waynedgrant.com/weather/api/weather.json', version=1.7, githubProject='null', copyright='Copyright © 2016 Wayne D Grant (www.waynedgrant.com)'}}
08-28 18:12:48.369 31253-31253/com.hari.daggerpoc D/ScreenB: Response cache -->WeatherResponse{endpoint=Endpoint{url='http://www.waynedgrant.com/weather/api/weather.json', version=1.7, githubProject='null', copyright='Copyright © 2016 Wayne D Grant (www.waynedgrant.com)'}}

关于android - Dagger 2 创建单例实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38997218/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com