Cache chapter images from presenter with glide.

This commit is contained in:
inorichi 2015-10-23 01:40:27 +02:00
parent fefc6ba0e9
commit ef7613f7ad
10 changed files with 93 additions and 71 deletions

View File

@ -5,10 +5,10 @@ import android.content.Context;
import org.acra.annotation.ReportsCrashes;
import eu.kanade.mangafeed.injection.component.AppComponent;
import eu.kanade.mangafeed.injection.module.AppModule;
import eu.kanade.mangafeed.injection.ComponentReflectionInjector;
import eu.kanade.mangafeed.injection.component.AppComponent;
import eu.kanade.mangafeed.injection.component.DaggerAppComponent;
import eu.kanade.mangafeed.injection.module.AppModule;
import timber.log.Timber;
@ReportsCrashes(

View File

@ -5,15 +5,17 @@ public class Page {
private int pageNumber;
private String url;
private String imageUrl;
private String imagePath;
public Page(int pageNumber, String url, String imageUrl) {
public Page(int pageNumber, String url, String imageUrl, String imagePath) {
this.pageNumber = pageNumber;
this.url = url;
this.imageUrl = imageUrl;
this.imagePath = imagePath;
}
public Page(int pageNumber, String url) {
this(pageNumber, url, null);
this(pageNumber, url, null, null);
}
public int getPageNumber() {
@ -32,6 +34,14 @@ public class Page {
this.imageUrl = imageUrl;
}
public String getImagePath() {
return imagePath;
}
public void setImagePath(String imagePath) {
this.imagePath = imagePath;
}
@Override
public String toString() {
return "Page{" +
@ -40,4 +50,5 @@ public class Page {
", imageUrl='" + imageUrl + '\'' +
'}';
}
}

View File

@ -2,6 +2,9 @@ package eu.kanade.mangafeed.injection.module;
import android.app.Application;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
import javax.inject.Singleton;
import dagger.Module;
@ -55,4 +58,10 @@ public class DataModule {
SourceManager provideSourceManager(NetworkHelper networkHelper, CacheManager cacheManager) {
return new SourceManager(networkHelper, cacheManager);
}
@Provides
@Singleton
RequestManager provideGlideDownloader(Application app) {
return Glide.with(app);
}
}

View File

@ -13,11 +13,11 @@ import eu.kanade.mangafeed.data.helpers.DatabaseHelper;
import eu.kanade.mangafeed.data.helpers.SourceManager;
import eu.kanade.mangafeed.data.models.Chapter;
import eu.kanade.mangafeed.data.models.Manga;
import eu.kanade.mangafeed.events.ChapterCountEvent;
import eu.kanade.mangafeed.events.SourceChapterEvent;
import eu.kanade.mangafeed.sources.Source;
import eu.kanade.mangafeed.ui.fragment.MangaChaptersFragment;
import eu.kanade.mangafeed.util.EventBusHook;
import eu.kanade.mangafeed.events.ChapterCountEvent;
import eu.kanade.mangafeed.events.SourceChapterEvent;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

View File

@ -6,9 +6,9 @@ import javax.inject.Inject;
import eu.kanade.mangafeed.data.helpers.DatabaseHelper;
import eu.kanade.mangafeed.data.models.Manga;
import eu.kanade.mangafeed.events.ChapterCountEvent;
import eu.kanade.mangafeed.ui.fragment.MangaInfoFragment;
import eu.kanade.mangafeed.util.EventBusHook;
import eu.kanade.mangafeed.events.ChapterCountEvent;
import rx.Observable;
public class MangaInfoPresenter extends BasePresenter<MangaInfoFragment> {

View File

@ -2,6 +2,11 @@ package eu.kanade.mangafeed.presenter;
import android.os.Bundle;
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.request.FutureTarget;
import com.bumptech.glide.request.target.Target;
import java.io.File;
import java.util.List;
import javax.inject.Inject;
@ -10,10 +15,10 @@ import de.greenrobot.event.EventBus;
import eu.kanade.mangafeed.data.helpers.PreferencesHelper;
import eu.kanade.mangafeed.data.models.Chapter;
import eu.kanade.mangafeed.data.models.Page;
import eu.kanade.mangafeed.events.SourceChapterEvent;
import eu.kanade.mangafeed.sources.Source;
import eu.kanade.mangafeed.ui.activity.ReaderActivity;
import eu.kanade.mangafeed.util.EventBusHook;
import eu.kanade.mangafeed.events.SourceChapterEvent;
import icepick.State;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
@ -22,6 +27,7 @@ import rx.schedulers.Schedulers;
public class ReaderPresenter extends BasePresenter<ReaderActivity> {
@Inject PreferencesHelper prefs;
@Inject RequestManager glideDownloader;
private Source source;
private Chapter chapter;
@ -97,10 +103,26 @@ public class ReaderPresenter extends BasePresenter<ReaderActivity> {
Observable.from(pageList).filter(page -> page.getImageUrl() != null),
source.getRemainingImageUrlsFromPageList(pageList)
.doOnNext(this::replacePageUrl))
.flatMap(this::downloadImage)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
private Observable<Page> downloadImage(Page page) {
FutureTarget<File> future = glideDownloader.load(page.getImageUrl())
.downloadOnly(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL);
try {
File cacheFile = future.get();
page.setImagePath(cacheFile.getCanonicalPath());
} catch (Exception e) {
e.printStackTrace();
}
return Observable.just(page);
}
private void replacePageUrl(Page page) {
for (int i = 0; i < pageList.size(); i++) {
if (pageList.get(i).getPageNumber() == page.getPageNumber()) {

View File

@ -46,7 +46,7 @@ public abstract class Source {
}
// Number of images to download at the same time
protected int getNumberOfConcurrentImageDownloads() {
protected int getNumberOfConcurrentPageDownloads() {
return 3;
}
@ -111,14 +111,10 @@ public abstract class Source {
public Observable<Page> getRemainingImageUrlsFromPageList(final List<Page> pages) {
return Observable.from(pages)
.filter(page -> page.getImageUrl() == null)
.buffer(getNumberOfConcurrentImageDownloads())
.concatMap(batchedPages -> {
List<Observable<Page>> pageObservable = new ArrayList<>();
for (Page page : batchedPages) {
pageObservable.add(getImageUrlFromPage(page));
}
return Observable.merge(pageObservable);
});
.window(getNumberOfConcurrentPageDownloads())
.concatMap(batchedPages ->
batchedPages.concatMap(this::getImageUrlFromPage)
);
}
private Observable<Page> getImageUrlFromPage(final Page page) {

View File

@ -6,27 +6,29 @@ import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import com.bumptech.glide.Glide;
import com.davemorrissey.labs.subscaleview.ImageSource;
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;
import butterknife.Bind;
import butterknife.ButterKnife;
import eu.kanade.mangafeed.R;
import eu.kanade.mangafeed.data.models.Page;
import eu.kanade.mangafeed.ui.activity.ReaderActivity;
import eu.kanade.mangafeed.util.MangaImageRegionDecoder;
import eu.kanade.mangafeed.util.PageFileTarget;
public class ReaderPageFragment extends Fragment {
public static final String URL_ARGUMENT_KEY = "UrlArgumentKey";
private SubsamplingScaleImageView imageView;
@Bind(R.id.page_image_view) SubsamplingScaleImageView imageView;
@Bind(R.id.progress) ProgressBar progressBar;
private String mUrl;
private String imagePath;
public static ReaderPageFragment newInstance(Page page) {
ReaderPageFragment newInstance = new ReaderPageFragment();
Bundle arguments = new Bundle();
arguments.putString(URL_ARGUMENT_KEY, page.getImageUrl());
arguments.putString(URL_ARGUMENT_KEY, page.getImagePath());
newInstance.setArguments(arguments);
return newInstance;
}
@ -40,39 +42,42 @@ public class ReaderPageFragment extends Fragment {
Bundle arguments = getArguments();
if (arguments != null) {
if (arguments.containsKey(URL_ARGUMENT_KEY)) {
mUrl = arguments.getString(URL_ARGUMENT_KEY);
imagePath = arguments.getString(URL_ARGUMENT_KEY);
}
}
}
public void setPage(Page page) {
if (!page.getImageUrl().equals(mUrl)) {
mUrl = page.getImageUrl();
if (!page.getImageUrl().equals(imagePath)) {
imagePath = page.getImagePath();
loadImage();
}
}
private void loadImage() {
if (mUrl != null) {
Glide.with(getActivity())
.load(mUrl)
.downloadOnly(new PageFileTarget(imageView));
if (imagePath != null) {
progressBar.setVisibility(View.GONE);
imageView.setImage(ImageSource.uri(imagePath).tilingDisabled());
}
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
imageView = (SubsamplingScaleImageView)inflater.inflate(R.layout.fragment_page, container, false);
View view = inflater.inflate(R.layout.fragment_page, container, false);
ButterKnife.bind(this, view);
imageView.setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_FIXED);
imageView.setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_INSIDE);
imageView.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CENTER_INSIDE);
imageView.setOnTouchListener((view, motionEvent) ->
imageView.setOnTouchListener((v, motionEvent) ->
((ReaderActivity) getActivity()).getViewPager().onImageTouch(motionEvent));
progressBar.setVisibility(View.VISIBLE);
loadImage();
return imageView;
return view;
}
}

View File

@ -1,36 +0,0 @@
package eu.kanade.mangafeed.util;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.ViewTarget;
import com.davemorrissey.labs.subscaleview.ImageSource;
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView;
import java.io.File;
import eu.kanade.mangafeed.R;
public class PageFileTarget extends ViewTarget<SubsamplingScaleImageView, File> {
public PageFileTarget(SubsamplingScaleImageView view) {
super(view);
}
@Override
public void onLoadCleared(Drawable placeholder) {
view.setImage(ImageSource.resource(R.drawable.ic_action_refresh));
}
@Override
public void onLoadStarted(Drawable placeholder) {
view.setImage(ImageSource.resource(R.drawable.ic_action_refresh));
}
@Override
public void onResourceReady(File resource, GlideAnimation<? super File> glideAnimation) {
view.setImage(ImageSource.uri(Uri.fromFile(resource))
.tilingDisabled());
}
}

View File

@ -1,6 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<ProgressBar
android:id="@+id/progress"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_gravity="center_vertical|center_horizontal"
android:visibility="gone" />
<com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/page_image_view" />
</FrameLayout>