diff --git a/app/build.gradle b/app/build.gradle
index 2c87053..cdb6f7d 100755
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -5,14 +5,14 @@ apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
- compileSdkVersion 28
+ compileSdkVersion 29
defaultConfig {
applicationId "com.nekodev.paulina.sadowska.progressiveloadingdemo"
minSdkVersion 17
- targetSdkVersion 28
+ targetSdkVersion 29
versionCode 1
- versionName "1.0"
- testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ versionName "2.0"
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
@@ -25,18 +25,28 @@ android {
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
- implementation 'com.android.support:appcompat-v7:28.0.0'
- implementation 'com.android.support.constraint:constraint-layout:1.1.3'
+ implementation 'androidx.appcompat:appcompat:1.1.0'
+ implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
- implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
- implementation 'io.reactivex.rxjava2:rxjava:2.2.2'
+ //
+ implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
+ implementation 'io.reactivex.rxjava2:rxjava:2.2.6'
implementation 'io.reactivex.rxjava2:rxkotlin:2.2.0'
+ //
+ //
implementation 'com.squareup.picasso:picasso:2.71828'
- implementation 'com.android.support:exifinterface:28.0.0'
- //force picasso to use newer support lib version
+ implementation 'com.jakewharton.picasso:picasso2-okhttp3-downloader:1.0.2'
+ //
- testImplementation 'junit:junit:4.12'
- androidTestImplementation 'com.android.support.test:runner:1.0.2'
- androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
+ //
+ implementation 'com.facebook.stetho:stetho:1.5.1'
+ implementation 'com.facebook.stetho:stetho-okhttp3:1.5.1' // for OkHttp library
+ //
+
+ //
+ testImplementation 'junit:junit:4.13'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.1'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
+ //
}
diff --git a/app/src/main/java/com/nekodev/paulina/sadowska/progressiveloadingdemo/ImageLoadingApplication.kt b/app/src/main/java/com/nekodev/paulina/sadowska/progressiveloadingdemo/ImageLoadingApplication.kt
index 5c850d2..4c193bc 100644
--- a/app/src/main/java/com/nekodev/paulina/sadowska/progressiveloadingdemo/ImageLoadingApplication.kt
+++ b/app/src/main/java/com/nekodev/paulina/sadowska/progressiveloadingdemo/ImageLoadingApplication.kt
@@ -1,14 +1,35 @@
package com.nekodev.paulina.sadowska.progressiveloadingdemo
import android.app.Application
+import com.facebook.stetho.Stetho
+import com.facebook.stetho.okhttp3.StethoInterceptor
+import com.squareup.picasso.OkHttp3Downloader
import com.squareup.picasso.Picasso
import io.reactivex.plugins.RxJavaPlugins
+import okhttp3.OkHttpClient
+import java.util.concurrent.TimeUnit
+
class ImageLoadingApplication : Application() {
override fun onCreate() {
super.onCreate()
+
RxJavaPlugins.setErrorHandler(RxJavaErrorHandler())
- Picasso.get().isLoggingEnabled = true
+
+ // open chrome://inspect/#devices on Chrome browse, then click on "inspect" link.
+ Stetho.initializeWithDefaults(this)
+
+ val client = OkHttpClient.Builder()
+ .connectTimeout(30, TimeUnit.SECONDS)
+ .addNetworkInterceptor(StethoInterceptor()) // add network interceptor
+ .build()
+
+ val instance = Picasso.Builder(this)
+ .downloader(OkHttp3Downloader(client)) // custom downloader
+ .loggingEnabled(true)
+ .build()
+
+ Picasso.setSingletonInstance(instance)
}
}
diff --git a/app/src/main/java/com/nekodev/paulina/sadowska/progressiveloadingdemo/ImageViewModel.kt b/app/src/main/java/com/nekodev/paulina/sadowska/progressiveloadingdemo/ImageViewModel.kt
index 2429ee5..411847e 100644
--- a/app/src/main/java/com/nekodev/paulina/sadowska/progressiveloadingdemo/ImageViewModel.kt
+++ b/app/src/main/java/com/nekodev/paulina/sadowska/progressiveloadingdemo/ImageViewModel.kt
@@ -1,6 +1,7 @@
package com.nekodev.paulina.sadowska.progressiveloadingdemo
-import android.arch.lifecycle.MutableLiveData
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
import com.nekodev.paulina.sadowska.progressiveloadingdemo.fetcher.ImageFetcher
import com.nekodev.paulina.sadowska.progressiveloadingdemo.fetcher.data.BitmapResult
import com.nekodev.paulina.sadowska.progressiveloadingdemo.fetcher.data.BitmapWithQuality
@@ -17,16 +18,28 @@ class ImageViewModel {
private val disposable = CompositeDisposable()
private val fetcher = ImageFetcher(Picasso.get())
- val bitmapResult = MutableLiveData()
+ private val _bitmapResult = MutableLiveData()
+
+ val bitmapResult: LiveData
+ get() = _bitmapResult
fun loadImages(qualities: List) {
- bitmapResult.value = BitmapResult.loading()
- disposable.add(fetcher.loadProgressively(BASE_IMAGE_URL, qualities)
- .filter { getCurrentQuality() < it.quality }
- .subscribeBy(
- onNext = { applyImage(it) },
- onComplete = { postErrorIfNotSufficientQuality() }
- ))
+ _bitmapResult.value = BitmapResult.loading()
+
+ disposable.add(
+ fetcher.loadProgressively(BASE_IMAGE_URL, qualities)
+ .doOnSubscribe { resetImageView() }
+ .filter { getCurrentQuality() < it.quality }
+ .subscribeBy(
+ onNext = { applyImage(it) },
+ onComplete = {
+ postErrorIfNotSufficientQuality()
+ }
+ ))
+ }
+
+ private fun resetImageView() {
+ _bitmapResult.value = BitmapResult.loading()
}
private fun getCurrentQuality(): Int {
@@ -34,12 +47,12 @@ class ImageViewModel {
}
private fun applyImage(bitmap: BitmapWithQuality) {
- bitmapResult.value = BitmapResult.success(bitmap)
+ _bitmapResult.value = BitmapResult.success(bitmap)
}
-
+
private fun postErrorIfNotSufficientQuality() {
if (getCurrentQuality() < 0) {
- bitmapResult.value = BitmapResult.error()
+ _bitmapResult.value = BitmapResult.error()
}
}
diff --git a/app/src/main/java/com/nekodev/paulina/sadowska/progressiveloadingdemo/MainActivity.kt b/app/src/main/java/com/nekodev/paulina/sadowska/progressiveloadingdemo/MainActivity.kt
index 1a29265..792539d 100755
--- a/app/src/main/java/com/nekodev/paulina/sadowska/progressiveloadingdemo/MainActivity.kt
+++ b/app/src/main/java/com/nekodev/paulina/sadowska/progressiveloadingdemo/MainActivity.kt
@@ -1,10 +1,10 @@
package com.nekodev.paulina.sadowska.progressiveloadingdemo
-import android.arch.lifecycle.Observer
import android.graphics.Bitmap
import android.os.Bundle
-import android.support.v7.app.AppCompatActivity
import android.view.View
+import androidx.appcompat.app.AppCompatActivity
+import androidx.lifecycle.Observer
import com.nekodev.paulina.sadowska.progressiveloadingdemo.fetcher.data.BitmapResult
import com.nekodev.paulina.sadowska.progressiveloadingdemo.fetcher.data.ResponseState
import kotlinx.android.synthetic.main.activity_main.*
@@ -17,8 +17,8 @@ class MainActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
- viewModel.bitmapResult.observe(this, Observer { it -> process(it) })
- viewModel.loadImages(listOf(3000, 10, 300))
+ viewModel.bitmapResult.observe(this, Observer { process(it) })
+ btn_load_image.setOnClickListener { viewModel.loadImages(listOf(3000, 10, 300)) }
}
private fun process(result: BitmapResult?) {
@@ -26,6 +26,7 @@ class MainActivity : AppCompatActivity() {
when (it.state) {
ResponseState.LOADING -> {
showProgress()
+ hideError()
}
ResponseState.ERROR -> {
hideProgress()
@@ -41,12 +42,17 @@ class MainActivity : AppCompatActivity() {
}
}
+ private fun hideError() {
+ errorText.visibility = View.GONE
+ }
+
private fun showImage(bitmap: Bitmap) {
imageView.setImageBitmap(bitmap)
}
private fun showProgress() {
loader.visibility = View.VISIBLE
+ imageView.setImageBitmap(null)
}
private fun hideProgress() {
diff --git a/app/src/main/java/com/nekodev/paulina/sadowska/progressiveloadingdemo/fetcher/ImageFetcher.kt b/app/src/main/java/com/nekodev/paulina/sadowska/progressiveloadingdemo/fetcher/ImageFetcher.kt
index 380c7ab..0b0a93a 100755
--- a/app/src/main/java/com/nekodev/paulina/sadowska/progressiveloadingdemo/fetcher/ImageFetcher.kt
+++ b/app/src/main/java/com/nekodev/paulina/sadowska/progressiveloadingdemo/fetcher/ImageFetcher.kt
@@ -10,6 +10,8 @@ import io.reactivex.Single
*/
class ImageFetcher(private val picasso: Picasso) {
+ private val pet = 237
+
fun loadProgressively(baseUrl: String, qualities: List): Observable {
return qualities
.map { quality -> Pair(createUrl(baseUrl, quality), quality) }
@@ -36,6 +38,6 @@ class ImageFetcher(private val picasso: Picasso) {
.onErrorResumeNext(Observable.empty())
}
- private fun createUrl(url: String, size: Int): String = "$url/$size/$size?image=0" //?image=0 added so image wont be random
+ private fun createUrl(url: String, size: Int): String = "$url/id/${pet}/$size/$size"
}
diff --git a/app/src/main/java/com/nekodev/paulina/sadowska/progressiveloadingdemo/fetcher/ImageFetcherSingleSubscribe.kt b/app/src/main/java/com/nekodev/paulina/sadowska/progressiveloadingdemo/fetcher/ImageFetcherSingleSubscribe.kt
index 78f4d26..34b5a9f 100755
--- a/app/src/main/java/com/nekodev/paulina/sadowska/progressiveloadingdemo/fetcher/ImageFetcherSingleSubscribe.kt
+++ b/app/src/main/java/com/nekodev/paulina/sadowska/progressiveloadingdemo/fetcher/ImageFetcherSingleSubscribe.kt
@@ -1,6 +1,8 @@
package com.nekodev.paulina.sadowska.progressiveloadingdemo.fetcher
import com.nekodev.paulina.sadowska.progressiveloadingdemo.fetcher.data.BitmapWithQuality
+import com.squareup.picasso.MemoryPolicy
+import com.squareup.picasso.NetworkPolicy
import com.squareup.picasso.Picasso
import com.squareup.picasso.Target
import io.reactivex.SingleEmitter
@@ -22,6 +24,8 @@ class ImageFetcherSingleSubscribe(private val picasso: Picasso,
runningTargets.add(target)
picasso.load(url)
+ .memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE) // avoiding cache to force reload
+ .networkPolicy(NetworkPolicy.NO_CACHE, NetworkPolicy.NO_STORE) // avoiding cache to force reload
.into(target)
}
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 0eb7f65..7dcd7c4 100755
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -1,28 +1,55 @@
-
+
+
+ android:layout_gravity="center"
+ android:visibility="gone"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ tools:visibility="visible" />
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/btn_load_image" />
+ android:visibility="gone"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ tools:visibility="visible" />
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index ff630b8..81605cb 100755
--- a/build.gradle
+++ b/build.gradle
@@ -1,13 +1,13 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
- ext.kotlin_version = '1.3.0'
+ ext.kotlin_version = '1.3.61'
repositories {
google()
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.2.1'
+ classpath 'com.android.tools.build:gradle:3.5.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
diff --git a/gradle.properties b/gradle.properties
index 743d692..8de5058 100755
--- a/gradle.properties
+++ b/gradle.properties
@@ -6,6 +6,8 @@
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
+android.enableJetifier=true
+android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 56bde43..4ddf9fc 100755
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Sun Nov 11 14:52:24 CET 2018
+#Mon Jan 13 19:53:30 BRST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip