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的字段中。

+1

完全正确! –

+0

哦!,所以...为什么我们打扰使用@singleton注释标注组件和模块? – feresr

+1

将一个范围注释添加到'@Provision'方法意味着该方法将在安装到其中的组件的一个实例中最多被调用一次。 否则,即使在一个组件实例中,每次调用Provider的get()方法时,都会再次调用@ @提供方法。每一个'@注入'RestRepository'的类都会得到一个新的实例。 – netdpb

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

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

一个范围依赖存在作为一个实例,每个组件。

如果您创建了一个新组件,它将拥有自己的作用域,并且它将创建自己的实例。

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