Donc, un peu de contexte. J'utilise Dagger2, Retrofit et RxAndroid et structurer mon application en utilisant une architecture MVP. Pour l'instant, tout ce que je fais est de faire une demande de réseau à l'API de récupérer des informations dès que mon activité principale commence. J'essaye de persister mes présentateurs à travers les changements de configuration pour éviter de faire une nouvelle requête http chaque fois que je fais pivoter mon écran.Dagger2 singleton annotation ne fonctionne pas
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());
}
}
Le constructeur de cette classe (présentateur) garde qui se fait appeler comme je tourne mon acitivité. J'ai annoté avec @Singleton la plupart de mes cours. Je ne sais pas quoi faire d'autre.
EDIT: Notez que je ne suis pas encore entré dans les SCOPES dagger, pour l'instant je me moque de savoir si ce présentateur singleton vit aussi longtemps que mon application. Je vais régler ça plus tard.
Complètement bien! –
Oh! Alors, pourquoi dérange-t-on l'annotation des composants et des modules avec l'annotation @singleton? – feresr
L'ajout d'une annotation de portée à une méthode '@ Provides' signifie que la méthode sera appelée au plus une fois dans une instance du composant dans lequel elle est installée.Sans cela, la méthode '@ Provides' serait appelée à chaque fois qu'une méthode' get() 'de' Provider' est appelée, même dans une instance de composant. Chaque classe qui '' @ Injects'' un 'RestRepository' obtiendrait une nouvelle instance. – netdpb