【发布时间】:2017-03-17 01:04:36
【问题描述】:
我遵循了网络上的一些教程和开源,并使用 RxJava、Dagger 2 和 Retrofit 构建了基于 MVP 架构的简单应用程序。一切正常,除了当我开始下载数据并立即旋转屏幕之前的请求被取消并发出新的请求时。
网络请求被取消的原因是我正在取消订阅我视图的onDestroyView 内的 Observable。那是为了防止内存泄漏!
如何保留以前的网络请求不让Subscription 泄漏?
这里是视图:
public class MoviesFragment extends Fragment implements MoviesView{
@Inject
MoviesPresenter moviesPresenter;
//....
public MoviesFragment(){
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
setRetainInstance(true);
((BaseApplication) getActivity().getApplication()).createListingComponent().inject(this);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_movies, container, false);
ButterKnife.bind(this, rootView);
return rootView;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
moviesPresenter.setView(this);
}
// ....
@Override
public void onDestroyView()
{
super.onDestroyView();
moviesPresenter.destroy();
ButterKnife.unbind(this);
}
@Override
public void onDetach()
{
super.onDetach();
}
@Override
public void onDestroy()
{
super.onDestroy();
((BaseApplication)getActivity().getApplication()).releaseListingComponent();
}
//....
}
这里是演示者:
public class MoviesPresenterImpl implements MoviesPresenter {
private final MoviesInteractor moviesInteractor;
private MoviesView view;
private Subscription fetchSubscription;
public MoviesPresenterImpl(MoviesInteractor moviesInteractor) {
this.moviesInteractor = moviesInteractor;
}
@Override
public void downloadMovies() {
fetchSubscription = moviesInteractor.getMovieList(new MoviesInteractorImpl.GetMovieListCallback() {
@Override
public void onSuccess(List<MovieModel> movieModels) {
onMovieFetchSuccess(movieModels);
}
@Override
public void onError(NetworkError networkError) {
onMovieFetchFailed(new Throwable(networkError));
}
});
}
@Override
public void setView(MoviesView view) {
this.view = view;
downloadMovies();
}
@Override
public void destroy() {
view = null;
fetchSubscription.unsubscribe();
}
private void onMovieFetchSuccess(List<MovieModel> movies) {
if (isViewAttached()) {
view.showMovies(movies);
}
}
//....
}
这里是 API 和 Presenter 之间的交互器:
public class MoviesInteractorImpl implements MoviesInteractor {
private Observable<MoviesResponseModel> call;
public MoviesInteractorImpl(MoviesRetrofitService moviesRetrofitService) {
call = moviesRetrofitService.getMovies("en", "popularity.desc", "MY_API_KEY");
}
@Override
public Subscription getMovieList(final GetMovieListCallback callback) {
return call
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<MoviesResponseModel>() {
@Override
public void onStart() {
super.onStart();
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
callback.onError(new NetworkError(e));
}
@Override
public void onNext(MoviesResponseModel cityListResponse) {
callback.onSuccess(cityListResponse.getMovieList());
}
});
}
public interface GetMovieListCallback {
void onSuccess(List<MovieModel> movieModels);
void onError(NetworkError networkError);
}
}
自定义范围,这样只要 View 还活着,Presenter 就会一直存在。
@Scope
@Retention(RetentionPolicy.RUNTIME)
public @interface ListingScope {
}
匕首模块:
@Module
public class ListingModule {
@Provides
public MoviesRetrofitService provideMoviesRetorfitService(Retrofit retrofit) {
return retrofit.create(MoviesRetrofitService.class);
}
@Provides
MoviesInteractor provideMoviesInteractor(MoviesRetrofitService moviesRetrofitService){
return new MoviesInteractorImpl(moviesRetrofitService);
}
@Provides
MoviesPresenter provideMoviesPresenter(MoviesInteractor moviesInteractor){
return new MoviesPresenterImpl(moviesInteractor);
}
}
匕首组件 - 子组件:
@ListingScope
@Subcomponent(modules = {ListingModule.class})
public interface ListingComponent {
MoviesFragment inject(MoviesFragment moviesFragment);
}
【问题讨论】:
标签: android mvp dagger-2 rx-android onconfigurationchanged