diff options
author | Allan Wang <me@allanwang.ca> | 2017-08-02 16:21:49 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-02 16:21:49 -0700 |
commit | 53382b44bb7ab7ccb559e96fd1f93c47020878ee (patch) | |
tree | 79c1862992f458ac52c1910b3a2e0c01cb7d5a5a /mediapicker/src/main/kotlin | |
parent | 7d894be6de118357ec908d2d171b6152ce67307d (diff) | |
download | kau-53382b44bb7ab7ccb559e96fd1f93c47020878ee.tar.gz kau-53382b44bb7ab7ccb559e96fd1f93c47020878ee.tar.bz2 kau-53382b44bb7ab7ccb559e96fd1f93c47020878ee.zip |
Improve video prefetching (#17)
* Create base activity and add thumbnails to media picker
* Add checker to see if requested permission is inside the manifest
* Add faq parser with tests
* Add kpref testers and expose sp
* Test jitpack sample exclusion
* Test caching
* Improve glide caching
Diffstat (limited to 'mediapicker/src/main/kotlin')
4 files changed, 48 insertions, 7 deletions
diff --git a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItem.kt b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItem.kt index 3947809..b6f3721 100644 --- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItem.kt +++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItem.kt @@ -40,6 +40,7 @@ class MediaItem(val data: MediaModel) super.bindView(holder, payloads) Glide.with(holder.itemView) .load(data.data) + .applyMediaOptions(holder.itemView.context) .listener(object : RequestListener<Drawable> { override fun onLoadFailed(e: GlideException?, model: Any, target: Target<Drawable>, isFirstResource: Boolean): Boolean { failedToLoad = true diff --git a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItemBasic.kt b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItemBasic.kt index 4fbe955..c28ed29 100644 --- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItemBasic.kt +++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaItemBasic.kt @@ -47,6 +47,7 @@ class MediaItemBasic(val data: MediaModel) super.bindView(holder, payloads) Glide.with(holder.itemView) .load(data.data) + .applyMediaOptions(holder.itemView.context) .listener(object : RequestListener<Drawable> { override fun onLoadFailed(e: GlideException?, model: Any, target: Target<Drawable>, isFirstResource: Boolean): Boolean { holder.image.setImageDrawable(MediaPickerCore.getErrorDrawable(holder.itemView.context)) diff --git a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerBinder.kt b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerBinder.kt index bdd25ba..cb218fc 100644 --- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerBinder.kt +++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerBinder.kt @@ -1,8 +1,12 @@ package ca.allanwang.kau.mediapicker import android.app.Activity +import android.content.Context import android.content.Intent import ca.allanwang.kau.utils.startActivityForResult +import com.bumptech.glide.RequestBuilder +import com.bumptech.glide.load.engine.DiskCacheStrategy +import com.bumptech.glide.request.RequestOptions /** * Created by Allan Wang on 2017-07-21. @@ -31,3 +35,6 @@ internal const val MEDIA_PICKER_RESULT = "media_picker_result" internal const val ANIMATION_DURATION = 200L internal const val ANIMATION_SCALE = 0.95f +internal fun <T> RequestBuilder<T>.applyMediaOptions(context: Context) + = apply(RequestOptions().diskCacheStrategy(DiskCacheStrategy.RESOURCE).centerCrop().override(MediaPickerCore.viewSize(context))) + diff --git a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerCore.kt b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerCore.kt index 255cec4..ee3481d 100644 --- a/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerCore.kt +++ b/mediapicker/src/main/kotlin/ca/allanwang/kau/mediapicker/MediaPickerCore.kt @@ -12,34 +12,42 @@ import android.provider.MediaStore import android.support.v4.app.LoaderManager import android.support.v4.content.CursorLoader import android.support.v4.content.Loader -import android.support.v7.app.AppCompatActivity import android.support.v7.widget.GridLayoutManager import android.support.v7.widget.RecyclerView import ca.allanwang.kau.animators.FadeScaleAnimatorAdd import ca.allanwang.kau.animators.KauAnimator +import ca.allanwang.kau.internal.KauBaseActivity +import ca.allanwang.kau.kotlin.lazyContext import ca.allanwang.kau.permissions.kauRequestPermissions import ca.allanwang.kau.utils.dimenPixelSize import ca.allanwang.kau.utils.toast +import com.bumptech.glide.Glide import com.mikepenz.fastadapter.IItem import com.mikepenz.fastadapter.commons.adapters.FastItemAdapter import com.mikepenz.google_material_typeface_library.GoogleMaterial import com.mikepenz.iconics.IconicsDrawable +import org.jetbrains.anko.doAsync +import java.util.concurrent.ExecutionException +import java.util.concurrent.Future /** * Created by Allan Wang on 2017-07-23. * * Container for the main logic behind the both pickers */ -abstract class MediaPickerCore<T : IItem<*, *>>(val mediaType: MediaType) : AppCompatActivity(), LoaderManager.LoaderCallbacks<Cursor> { +abstract class MediaPickerCore<T : IItem<*, *>>( + val mediaType: MediaType, val preload: Boolean = mediaType == MediaType.VIDEO +) : KauBaseActivity(), LoaderManager.LoaderCallbacks<Cursor> { companion object { + val viewSize = lazyContext { computeViewSize(it) } /** * Given the dimensions of our device and a minimum image size, * Computer the optimal column count for our grid layout * * @return column count */ - fun computeColumnCount(context: Context): Int { + private fun computeColumnCount(context: Context): Int { val minImageSizePx = context.dimenPixelSize(R.dimen.kau_image_minimum_size) val screenWidthPx = context.resources.displayMetrics.widthPixels return screenWidthPx / minImageSizePx @@ -48,7 +56,7 @@ abstract class MediaPickerCore<T : IItem<*, *>>(val mediaType: MediaType) : AppC /** * Compute our resulting image size */ - fun computeViewSize(context: Context): Int { + private fun computeViewSize(context: Context): Int { val screenWidthPx = context.resources.displayMetrics.widthPixels return screenWidthPx / computeColumnCount(context) } @@ -84,6 +92,9 @@ abstract class MediaPickerCore<T : IItem<*, *>>(val mediaType: MediaType) : AppC const val CACHE_SIZE = 80 } + private var hasPreloaded = false + private var prefetcher: Future<*>? = null + val adapter: FastItemAdapter<T> = FastItemAdapter() /** @@ -140,13 +151,30 @@ abstract class MediaPickerCore<T : IItem<*, *>>(val mediaType: MediaType) : AppC onStatusChange(false) return } - val items = mutableListOf<T>() + val models = mutableListOf<MediaModel>() do { val model = MediaModel(data) if (!shouldLoad(model)) continue - items.add(converter(model)) + models.add(model) } while (data.moveToNext()) - addItems(items) + addItems(models.map { converter(it) }) + if (!hasPreloaded && preload) { + hasPreloaded = true + prefetcher = doAsync { + models.subList(0, Math.min(models.size, 50)).map { it.data }.forEach { + val target = Glide.with(this@MediaPickerCore).load(it) + .applyMediaOptions(this@MediaPickerCore) + .submit() + try { + target.get() + } catch (ignored: InterruptedException) { + } catch (ignored: ExecutionException) { + } finally { + Glide.with(this@MediaPickerCore).clear(target) + } + } + } + } } abstract fun converter(model: MediaModel): T @@ -179,4 +207,8 @@ abstract class MediaPickerCore<T : IItem<*, *>>(val mediaType: MediaType) : AppC open fun onStatusChange(loaded: Boolean) {} + override fun onDestroy() { + prefetcher?.cancel(true) + super.onDestroy() + } }
\ No newline at end of file |