我在网上关注了几个教程和开源资源,并使用RxJava,Dagger 2和Retrofit构建了基于MVP体系结构的简单应用。一切工作正常,除非我开始下载数据,并立即旋转屏幕前一个请求被取消,并正在提出新的请求。Android 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和主持人之间的交互器:
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);
}
}
自定义范围,使演示者停留,只要查看活着。
@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);
}
从文档中的“处理配置改变自己可以使它更难以利用替代资源,因为系统不会自动应用它们。这种技术应被视为最后的手段,当你必须避免重新启动由于配置更改,不建议大多数应用程序。“ – Shmuel