Dagger2单身注释不起作用
问题描述:
所以,有点上下文。我使用Dagger2,Retrofit和RxAndroid,并使用MVP架构构建我的应用程序。Dagger2单身注释不起作用
现在,我所做的只是向API发出网络请求,并在我的主要活动开始后立即检索一些信息。我试图通过配置更改来坚持我的演示者,以避免每次旋转屏幕时都发出新的http请求。
MainActivity.java
public class MainActivity extends AppCompatActivity implements ForecastView {
@Inject
Presenter forecastPresenter;
private TextView text;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.weather);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
initializeDependencies();
initializePresenter();
}
private void initializeDependencies() {
DaggerWeatherApiComponent.builder()
.build().inject(this);
}
private void initializePresenter() {
forecastPresenter.attachView(this);
forecastPresenter.onCreate();
}
WeatherApiComponent.java
@Component(modules = {EndpointsModule.class})
@Singleton
public interface WeatherApiComponent {
void inject(MainActivity context);
}
EndpointsModule.java
@Module @Singleton
public class EndpointsModule {
@Provides
@Singleton
WeatherEndpoints provideEndpoints() {
Retrofit retrofit = new Retrofit.Builder()
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(new OkHttpClient())
.baseUrl("http://api.openweathermap.org/data/2.5/")
.build();
return retrofit.create(WeatherEndpoints.class);
}
@Provides
@Singleton
Repository providesRepository(RestRepository repository) {
return repository;
}
@Provides
@Singleton
Presenter providesPresenter(ForecastPresenter presenter) {
return presenter;
}
}
RestRespository
public class RestRepository implements Repository {
private WeatherEndpoints endpoints;
static final String API_KEY = "xxxxxxxxxxxxxxxxxxxxx";
@Inject
public RestRepository(WeatherEndpoints endpoints) {
this.endpoints = endpoints;
}
public Observable<Current> getCurrentWeather(String cityName) {
return endpoints.getCurrent(cityName, API_KEY);
}
public Observable<com.feresr.rxweather.models.List> getForecast(String cityName) {
return endpoints.getForecast(cityName, API_KEY).flatMap(new Func1<FiveDays, Observable<com.feresr.rxweather.models.List>>() {
@Override
public Observable<com.feresr.rxweather.models.List> call(FiveDays fiveDays) {
return Observable.from(fiveDays.getList());
}
});
}
}
ForecastPresenter.java
public class ForecastPresenter implements Presenter {
private GetForecastUseCase useCase;
private Subscription forecastSubscription;
private ArrayList<List> lists;
private ForecastView forecastView;
@Inject
public ForecastPresenter(GetForecastUseCase forecastUseCase) {
this.useCase = forecastUseCase;
lists = new ArrayList<>();
}
@Override
public void onStop() {
if (forecastSubscription.isUnsubscribed()) {
forecastSubscription.unsubscribe();
}
}
@Override
public void attachView(View v) {
forecastView = (ForecastView) v;
}
@Override
public void onCreate() {
if (lists.isEmpty()) {
forecastSubscription = useCase.execute().subscribe(new Action1<List>() {
@Override
public void call(List list) {
lists.add(list);
forecastView.addForecast(list.getWeather().get(0).getMain());
}
});
} else {
forecastView.addForecast(lists.get(0).toString());
}
}
这个类(主持人)构造函数保持自称为我转动我的活性。我用@Singleton注释了大部分课程。我不知道还有什么要做。
编辑:请注意,我还没有进入匕首范围,现在我不在乎,如果这个单身节目主持人只要我的应用程序生活。我稍后会解决这个问题。
答
看起来您每次调用MainActivity.onCreate(Bundle)
时都会重新创建Dagger组件,并且在旋转屏幕时该活动会重新生成。
与其他示波器一样,@Singleton
表示对于组件的生命周期,对于JVM的生命周期不会有一个对象的实例。您通常必须确保自己只有一个@Singleton
组件实例,通常通过将其保存在您的Application
的字段中。
答
您在这里创建一个新的匕首组件每次:
private void initializeDependencies() {
DaggerWeatherApiComponent.builder()
.build().inject(this);
}
一个范围依赖存在作为一个实例,每个组件。
如果您创建了一个新组件,它将拥有自己的作用域,并且它将创建自己的实例。
您应该投资Mortar
范围来保留您的组件,或者您的Application
实例中应该有某种“缓存”。
完全正确! –
哦!,所以...为什么我们打扰使用@singleton注释标注组件和模块? – feresr
将一个范围注释添加到'@Provision'方法意味着该方法将在安装到其中的组件的一个实例中最多被调用一次。 否则,即使在一个组件实例中,每次调用Provider的get()方法时,都会再次调用@ @提供方法。每一个'@注入'RestRepository'的类都会得到一个新的实例。 – netdpb