Dagger2单例注释不起作用

时间:2015-10-15 15:30:03

标签: android dagger-2

所以,有点背景。我正在使用Dagger2,Retrofit和RxAndroid,并使用MVP架构构建我的应用程序。

目前,我所做的就是向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());
    }
}

这个类(presenter)上的构造函数在旋转我的Acitivity时不断调用自身。我的大部分课程都是用@Singleton注释的。我不知道还能做什么。

编辑:请注意,我还没有进入匕首SCOPES,现在我不在乎这个单身主持人和我的应用程序一样长。我稍后会解决这个问题。

2 个答案:

答案 0 :(得分:4)

看起来您每次调用MainActivity.onCreate(Bundle)时都会重新创建Dagger组件,并且在您旋转屏幕时会重新激活该活动。

与其他范围一样,@Singleton表示组件的生命周期中将有一个对象的实例,而不是JVM的生命周期。您通常必须确保自己只有一个@Singleton组件实例,通常是将其保存在Application的字段中。

答案 1 :(得分:1)

每次在这里创建一个新的匕首组件:

private void initializeDependencies() {
    DaggerWeatherApiComponent.builder()
            .build().inject(this);
}

作用域依赖项存在为ONE实例PER组件。

如果您创建一个新组件,它将拥有自己的范围,并将创建自己的实例。

您应该投资Mortar范围来保留您的组件,或者您应该在Application实例中使用某种“缓存”。