From c67bb7694b2bd26c6a40fd6206fbf9d73b993221 Mon Sep 17 00:00:00 2001 From: Deepankar Date: Sun, 10 Sep 2017 20:25:11 +0530 Subject: [PATCH 1/3] * Upgraded android gradle plugin to 3.0.0-beta4. * Upgraded some dependencies to their latest version. * Bumped compileSdk and targetSdk to android O (26). --- app/build.gradle | 100 ++++++++++-------- .../DatabaseHelperTest.java | 4 +- build.gradle | 6 +- gradle/wrapper/gradle-wrapper.properties | 4 +- 4 files changed, 64 insertions(+), 50 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index e14537a4..b4ad3a80 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,17 +5,23 @@ apply plugin: 'com.github.triplet.play' //apply plugin: 'io.fabric' android { - compileSdkVersion 24 - buildToolsVersion '24.0.2' + compileSdkVersion 26 + buildToolsVersion '26.0.1' defaultConfig { applicationId 'uk.co.ribot.androidboilerplate' minSdkVersion 16 - targetSdkVersion 24 + targetSdkVersion 26 testInstrumentationRunner "${applicationId}.runner.RxAndroidJUnitRunner" versionCode 1000 // Major -> Millions, Minor -> Thousands, Bugfix -> Hundreds. E.g 1.3.72 == 1,003,072 versionName '0.1.0' + + javaCompileOptions { + annotationProcessorOptions { + includeCompileClasspath false + } + } } signingConfigs { @@ -68,6 +74,12 @@ android { lintOptions { warning 'InvalidPackage' } + + testOptions { + unitTests { + includeAndroidResources = true + } + } } play { @@ -78,84 +90,84 @@ play { } dependencies { - final PLAY_SERVICES_VERSION = '9.6.1' - final SUPPORT_LIBRARY_VERSION = '24.2.1' + final PLAY_SERVICES_VERSION = '11.2.2' + final SUPPORT_LIBRARY_VERSION = '26.0.2' final RETROFIT_VERSION = '2.1.0' final DAGGER_VERSION = '2.5' final MOCKITO_VERSION = '2.6.2' final HAMCREST_VERSION = '1.3' final ESPRESSO_VERSION = '2.2.1' final RUNNER_VERSION = '0.4' - final BUTTERKNIFE_VERSION = '8.4.0' - final AUTO_VALUE_VERSION = '1.3' - final AUTO_VALUE_GSON_VERSION = '0.4.2' + final BUTTERKNIFE_VERSION = '8.8.1' + final AUTO_VALUE_VERSION = '1.5' + final AUTO_VALUE_GSON_VERSION = '0.5.0' def daggerCompiler = "com.google.dagger:dagger-compiler:$DAGGER_VERSION" def jUnit = "junit:junit:4.12" def mockito = "org.mockito:mockito-core:$MOCKITO_VERSION" // App Dependencies - compile "com.google.android.gms:play-services-gcm:$PLAY_SERVICES_VERSION" - compile "com.android.support:appcompat-v7:$SUPPORT_LIBRARY_VERSION" - compile "com.android.support:recyclerview-v7:$SUPPORT_LIBRARY_VERSION" - compile "com.android.support:cardview-v7:$SUPPORT_LIBRARY_VERSION" - compile "com.android.support:support-annotations:$SUPPORT_LIBRARY_VERSION" + implementation "com.google.android.gms:play-services-gcm:$PLAY_SERVICES_VERSION" + implementation "com.android.support:appcompat-v7:$SUPPORT_LIBRARY_VERSION" + implementation "com.android.support:recyclerview-v7:$SUPPORT_LIBRARY_VERSION" + implementation "com.android.support:cardview-v7:$SUPPORT_LIBRARY_VERSION" + implementation "com.android.support:support-annotations:$SUPPORT_LIBRARY_VERSION" - compile ("com.squareup.sqlbrite:sqlbrite:1.1.1") { + implementation ("com.squareup.sqlbrite:sqlbrite:1.1.1") { exclude group: 'com.android.support', module: 'support-annotations' } - compile "com.squareup.retrofit2:retrofit:$RETROFIT_VERSION" - compile "com.squareup.retrofit2:converter-gson:$RETROFIT_VERSION" - compile "com.squareup.retrofit2:adapter-rxjava:$RETROFIT_VERSION" - - compile 'com.github.bumptech.glide:glide:3.7.0' - compile 'io.reactivex:rxandroid:1.2.1' - compile 'io.reactivex:rxjava:1.1.6' - compile('com.crashlytics.sdk.android:crashlytics:2.5.7@aar') { + implementation "com.squareup.retrofit2:retrofit:$RETROFIT_VERSION" + implementation "com.squareup.retrofit2:converter-gson:$RETROFIT_VERSION" + implementation "com.squareup.retrofit2:adapter-rxjava:$RETROFIT_VERSION" + + implementation 'com.github.bumptech.glide:glide:3.7.0' + implementation 'io.reactivex:rxandroid:1.2.1' + implementation 'io.reactivex:rxjava:1.2.3' + implementation('com.crashlytics.sdk.android:crashlytics:2.5.7@aar') { transitive = true; } - compile 'com.jakewharton.timber:timber:4.1.2' - compile "com.jakewharton:butterknife:$BUTTERKNIFE_VERSION" + implementation 'com.jakewharton.timber:timber:4.5.1' + implementation "com.jakewharton:butterknife:$BUTTERKNIFE_VERSION" annotationProcessor "com.jakewharton:butterknife-compiler:$BUTTERKNIFE_VERSION" // Replace provided dependency below with official AutoValue once this issue is fixed // https://github.com/google/auto/issues/268 - provided "com.jakewharton.auto.value:auto-value-annotations:$AUTO_VALUE_VERSION" - provided "com.ryanharter.auto.value:auto-value-gson:$AUTO_VALUE_GSON_VERSION" + compileOnly "com.jakewharton.auto.value:auto-value-annotations:$AUTO_VALUE_VERSION" + compileOnly "com.ryanharter.auto.value:auto-value-gson:$AUTO_VALUE_GSON_VERSION" annotationProcessor "com.google.auto.value:auto-value:$AUTO_VALUE_VERSION" - annotationProcessor 'com.ryanharter.auto.value:auto-value-parcel:0.2.4-rc2' + annotationProcessor 'com.ryanharter.auto.value:auto-value-parcel:0.2.5' annotationProcessor "com.ryanharter.auto.value:auto-value-gson:$AUTO_VALUE_GSON_VERSION" - annotationProcessor 'com.squareup:javapoet:1.7.0' + annotationProcessor 'com.squareup:javapoet:1.9.0' // https://github.com/rharter/auto-value-parcel/issues/64 - compile "com.google.dagger:dagger:$DAGGER_VERSION" - provided 'org.glassfish:javax.annotation:10.0-b28' //Required by Dagger2 + implementation "com.google.dagger:dagger:$DAGGER_VERSION" + compileOnly 'org.glassfish:javax.annotation:10.0-b28' //Required by Dagger2 annotationProcessor daggerCompiler testAnnotationProcessor daggerCompiler androidTestAnnotationProcessor daggerCompiler // Instrumentation test dependencies - androidTestCompile jUnit - androidTestCompile mockito - androidTestCompile "org.mockito:mockito-android:$MOCKITO_VERSION" - androidTestCompile "com.android.support:support-annotations:$SUPPORT_LIBRARY_VERSION" - androidTestCompile("com.android.support.test.espresso:espresso-contrib:$ESPRESSO_VERSION") { + androidTestImplementation jUnit + androidTestImplementation mockito + androidTestImplementation "org.mockito:mockito-android:$MOCKITO_VERSION" + androidTestImplementation "com.android.support:support-annotations:$SUPPORT_LIBRARY_VERSION" + androidTestImplementation("com.android.support.test.espresso:espresso-contrib:$ESPRESSO_VERSION") { exclude group: 'com.android.support', module: 'appcompat' exclude group: 'com.android.support', module: 'support-v4' exclude group: 'com.android.support', module: 'recyclerview-v7' } - androidTestCompile "com.android.support.test.espresso:espresso-core:$ESPRESSO_VERSION" - androidTestCompile "com.android.support.test:runner:$RUNNER_VERSION" - androidTestCompile "com.android.support.test:rules:$RUNNER_VERSION" + androidTestImplementation "com.android.support.test.espresso:espresso-core:$ESPRESSO_VERSION" + androidTestImplementation "com.android.support.test:runner:$RUNNER_VERSION" + androidTestImplementation "com.android.support.test:rules:$RUNNER_VERSION" // Unit tests dependencies - testCompile jUnit - testCompile mockito - testCompile "org.hamcrest:hamcrest-core:$HAMCREST_VERSION" - testCompile "org.hamcrest:hamcrest-library:$HAMCREST_VERSION" - testCompile "org.hamcrest:hamcrest-integration:$HAMCREST_VERSION" - testCompile 'org.robolectric:robolectric:3.1' + testImplementation jUnit + testImplementation mockito + testImplementation "org.hamcrest:hamcrest-core:$HAMCREST_VERSION" + testImplementation "org.hamcrest:hamcrest-library:$HAMCREST_VERSION" + testImplementation "org.hamcrest:hamcrest-integration:$HAMCREST_VERSION" + testImplementation 'org.robolectric:robolectric:3.4.2' } // Log out test results to console diff --git a/app/src/test/java/uk/co/ribot/androidboilerplate/DatabaseHelperTest.java b/app/src/test/java/uk/co/ribot/androidboilerplate/DatabaseHelperTest.java index 5b6d5614..1a9716d5 100644 --- a/app/src/test/java/uk/co/ribot/androidboilerplate/DatabaseHelperTest.java +++ b/app/src/test/java/uk/co/ribot/androidboilerplate/DatabaseHelperTest.java @@ -5,7 +5,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.RobolectricGradleTestRunner; +import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; @@ -26,7 +26,7 @@ /** * Unit tests integration with a SQLite Database using Robolectric */ -@RunWith(RobolectricGradleTestRunner.class) +@RunWith(RobolectricTestRunner.class) @Config(constants = BuildConfig.class, sdk = DefaultConfig.EMULATE_SDK) public class DatabaseHelperTest { diff --git a/build.gradle b/build.gradle index 12c5c7a3..c92601fa 100644 --- a/build.gradle +++ b/build.gradle @@ -1,11 +1,12 @@ buildscript { repositories { jcenter() + google() maven { url 'https://maven.fabric.io/public' } } dependencies { - classpath 'com.android.tools.build:gradle:2.2.0' - classpath 'com.github.triplet.gradle:play-publisher:1.1.4' + classpath 'com.android.tools.build:gradle:3.0.0-beta4' + classpath 'com.github.triplet.gradle:play-publisher:1.2.0' //noinspection GradleDynamicVersion classpath 'io.fabric.tools:gradle:1.+' } @@ -14,6 +15,7 @@ buildscript { allprojects { repositories { jcenter() + google() maven { url 'https://maven.fabric.io/public' } } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 7bbc95e7..0fa26fa8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Wed Sep 21 16:15:04 CST 2016 +#Sun Sep 10 09:57:32 IST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip From 9af40b8190ce238b228557d79e3bf521c4c341d4 Mon Sep 17 00:00:00 2001 From: Deepankar Date: Fri, 10 Nov 2017 19:36:22 +0530 Subject: [PATCH 2/3] Merged from upstream. --- app/build.gradle | 14 +-- .../androidboilerplate/MainActivityTest.java | 4 +- .../runner/RxAndroidJUnitRunner.java | 9 +- .../util/RxEspressoScheduleHandler.java | 42 +++++++++ .../util/RxIdlingResource.java | 87 ------------------- .../androidboilerplate/data/DataManager.java | 11 ++- .../androidboilerplate/data/SyncService.java | 33 ++++--- .../data/local/DatabaseHelper.java | 37 +++++--- .../data/remote/RibotsService.java | 6 +- .../ui/base/BaseActivity.java | 15 ++-- .../ui/main/MainPresenter.java | 41 +++++---- .../androidboilerplate/util/NetworkUtil.java | 2 +- .../androidboilerplate/util/RxEventBus.java | 17 ++-- .../ribot/androidboilerplate/util/RxUtil.java | 9 +- .../androidboilerplate/DataManagerTest.java | 12 +-- .../DatabaseHelperTest.java | 23 +++-- .../androidboilerplate/MainPresenterTest.java | 2 +- .../util/RxEventBusTest.java | 2 +- .../util/RxSchedulersOverrideRule.java | 58 +++++++------ build.gradle | 4 +- 20 files changed, 214 insertions(+), 214 deletions(-) create mode 100644 app/src/androidTest/java/uk/co/ribot/androidboilerplate/util/RxEspressoScheduleHandler.java delete mode 100644 app/src/androidTest/java/uk/co/ribot/androidboilerplate/util/RxIdlingResource.java diff --git a/app/build.gradle b/app/build.gradle index b4ad3a80..57419529 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,7 +6,7 @@ apply plugin: 'com.github.triplet.play' android { compileSdkVersion 26 - buildToolsVersion '26.0.1' + buildToolsVersion '26.0.2' defaultConfig { applicationId 'uk.co.ribot.androidboilerplate' @@ -90,9 +90,9 @@ play { } dependencies { - final PLAY_SERVICES_VERSION = '11.2.2' + final PLAY_SERVICES_VERSION = '11.4.2' final SUPPORT_LIBRARY_VERSION = '26.0.2' - final RETROFIT_VERSION = '2.1.0' + final RETROFIT_VERSION = '2.3.0' final DAGGER_VERSION = '2.5' final MOCKITO_VERSION = '2.6.2' final HAMCREST_VERSION = '1.3' @@ -113,16 +113,16 @@ dependencies { implementation "com.android.support:cardview-v7:$SUPPORT_LIBRARY_VERSION" implementation "com.android.support:support-annotations:$SUPPORT_LIBRARY_VERSION" - implementation ("com.squareup.sqlbrite:sqlbrite:1.1.1") { + implementation("com.squareup.sqlbrite2:sqlbrite:2.0.0") { exclude group: 'com.android.support', module: 'support-annotations' } implementation "com.squareup.retrofit2:retrofit:$RETROFIT_VERSION" implementation "com.squareup.retrofit2:converter-gson:$RETROFIT_VERSION" - implementation "com.squareup.retrofit2:adapter-rxjava:$RETROFIT_VERSION" + implementation "com.squareup.retrofit2:adapter-rxjava2:$RETROFIT_VERSION" implementation 'com.github.bumptech.glide:glide:3.7.0' - implementation 'io.reactivex:rxandroid:1.2.1' - implementation 'io.reactivex:rxjava:1.2.3' + implementation 'io.reactivex.rxjava2:rxandroid:2.0.1' + implementation 'io.reactivex.rxjava2:rxjava:2.1.3' implementation('com.crashlytics.sdk.android:crashlytics:2.5.7@aar') { transitive = true; } diff --git a/app/src/androidTest/java/uk/co/ribot/androidboilerplate/MainActivityTest.java b/app/src/androidTest/java/uk/co/ribot/androidboilerplate/MainActivityTest.java index 133fc801..d7ec73af 100644 --- a/app/src/androidTest/java/uk/co/ribot/androidboilerplate/MainActivityTest.java +++ b/app/src/androidTest/java/uk/co/ribot/androidboilerplate/MainActivityTest.java @@ -14,7 +14,7 @@ import java.util.List; -import rx.Observable; +import io.reactivex.Observable; import uk.co.ribot.androidboilerplate.data.model.Ribot; import uk.co.ribot.androidboilerplate.test.common.TestComponentRule; import uk.co.ribot.androidboilerplate.test.common.TestDataFactory; @@ -71,4 +71,4 @@ public void listOfRibotsShows() { } } -} \ No newline at end of file +} diff --git a/app/src/androidTest/java/uk/co/ribot/androidboilerplate/runner/RxAndroidJUnitRunner.java b/app/src/androidTest/java/uk/co/ribot/androidboilerplate/runner/RxAndroidJUnitRunner.java index 32b6e0e7..17cd6e0d 100644 --- a/app/src/androidTest/java/uk/co/ribot/androidboilerplate/runner/RxAndroidJUnitRunner.java +++ b/app/src/androidTest/java/uk/co/ribot/androidboilerplate/runner/RxAndroidJUnitRunner.java @@ -3,7 +3,8 @@ import android.os.Bundle; import android.support.test.espresso.Espresso; -import uk.co.ribot.androidboilerplate.util.RxIdlingResource; +import io.reactivex.plugins.RxJavaPlugins; +import uk.co.ribot.androidboilerplate.util.RxEspressoScheduleHandler; /** * Runner that registers a Espresso Indling resource that handles waiting for @@ -16,8 +17,10 @@ public class RxAndroidJUnitRunner extends UnlockDeviceAndroidJUnitRunner { @Override public void onCreate(Bundle arguments) { super.onCreate(arguments); - RxIdlingResource rxIdlingResource = new RxIdlingResource(); - Espresso.registerIdlingResources(rxIdlingResource); + + RxEspressoScheduleHandler rxEspressoScheduleHandler = new RxEspressoScheduleHandler(); + RxJavaPlugins.setScheduleHandler(rxEspressoScheduleHandler); + Espresso.registerIdlingResources(rxEspressoScheduleHandler.getIdlingResource()); } } diff --git a/app/src/androidTest/java/uk/co/ribot/androidboilerplate/util/RxEspressoScheduleHandler.java b/app/src/androidTest/java/uk/co/ribot/androidboilerplate/util/RxEspressoScheduleHandler.java new file mode 100644 index 00000000..1c8d6d51 --- /dev/null +++ b/app/src/androidTest/java/uk/co/ribot/androidboilerplate/util/RxEspressoScheduleHandler.java @@ -0,0 +1,42 @@ +package uk.co.ribot.androidboilerplate.util; + +import android.support.test.espresso.IdlingResource; +import android.support.test.espresso.contrib.CountingIdlingResource; + +import io.reactivex.annotations.NonNull; +import io.reactivex.functions.Function; + +/** + * Espresso Idling resource that handles waiting for RxJava Observables executions. + * This class must be used with RxIdlingExecutionHook. + * Before registering this idling resource you must: + * 1. Create an instance of this class. + * 2. Register RxEspressoScheduleHandler with the RxJavaPlugins using setScheduleHandler() + * 3. Register this idle resource with Espresso using Espresso.registerIdlingResources() + */ +public class RxEspressoScheduleHandler implements Function { + + private final CountingIdlingResource mCountingIdlingResource = + new CountingIdlingResource("rxJava"); + + @Override + public Runnable apply(@NonNull final Runnable runnable) throws Exception { + return new Runnable() { + @Override + public void run() { + mCountingIdlingResource.increment(); + + try { + runnable.run(); + } finally { + mCountingIdlingResource.decrement(); + } + } + }; + } + + public IdlingResource getIdlingResource() { + return mCountingIdlingResource; + } + +} diff --git a/app/src/androidTest/java/uk/co/ribot/androidboilerplate/util/RxIdlingResource.java b/app/src/androidTest/java/uk/co/ribot/androidboilerplate/util/RxIdlingResource.java deleted file mode 100644 index 92f4f6d4..00000000 --- a/app/src/androidTest/java/uk/co/ribot/androidboilerplate/util/RxIdlingResource.java +++ /dev/null @@ -1,87 +0,0 @@ -package uk.co.ribot.androidboilerplate.util; - -import android.support.test.espresso.IdlingResource; - -import java.util.concurrent.atomic.AtomicInteger; - -import rx.Observable; -import rx.Observable.OnSubscribe; -import rx.Subscription; -import rx.functions.Func1; -import rx.functions.Func2; -import rx.plugins.RxJavaHooks; -import timber.log.Timber; - -/** - * Espresso Idling resource that handles waiting for RxJava Observables executions. - * This class must be used with RxIdlingExecutionHook. - * Before registering this idling resource you must: - * 1. Create an instance of RxIdlingExecutionHook by passing an instance of this class. - * 2. Register RxIdlingExecutionHook with the RxJavaPlugins using registerObservableExecutionHook() - * 3. Register this idle resource with Espresso using Espresso.registerIdlingResources() - */ -public class RxIdlingResource implements IdlingResource { - - private final AtomicInteger mActiveSubscriptionsCount = new AtomicInteger(0); - private ResourceCallback mResourceCallback; - - public RxIdlingResource() { - setupHooks(); - } - - @Override - public String getName() { - return getClass().getSimpleName(); - } - - @Override - public boolean isIdleNow() { - return mActiveSubscriptionsCount.get() == 0; - } - - @Override - public void registerIdleTransitionCallback(ResourceCallback callback) { - mResourceCallback = callback; - } - - private void setupHooks() { - RxJavaHooks.setOnObservableStart(new Func2() { - @Override - public OnSubscribe call(Observable observable, OnSubscribe onSubscribe) { - incrementActiveSubscriptionsCount(); - return onSubscribe; - } - }); - - RxJavaHooks.setOnObservableSubscribeError(new Func1() { - @Override - public Throwable call(Throwable throwable) { - decrementActiveSubscriptionsCount(); - return throwable; - } - }); - - RxJavaHooks.setOnObservableReturn(new Func1() { - @Override - public Subscription call(Subscription subscription) { - decrementActiveSubscriptionsCount(); - return subscription; - } - }); - } - - private void incrementActiveSubscriptionsCount() { - int count = mActiveSubscriptionsCount.incrementAndGet(); - Timber.i("Active subscriptions count increased to %d", count); - } - - private void decrementActiveSubscriptionsCount() { - int count = mActiveSubscriptionsCount.decrementAndGet(); - Timber.i("Active subscriptions count decreased to %d", count); - if (isIdleNow()) { - Timber.i("There is no active subscriptions, transitioning to Idle"); - mResourceCallback.onTransitionToIdle(); - } - } - -} diff --git a/app/src/main/java/uk/co/ribot/androidboilerplate/data/DataManager.java b/app/src/main/java/uk/co/ribot/androidboilerplate/data/DataManager.java index 84bd4539..8c457f3c 100644 --- a/app/src/main/java/uk/co/ribot/androidboilerplate/data/DataManager.java +++ b/app/src/main/java/uk/co/ribot/androidboilerplate/data/DataManager.java @@ -5,8 +5,10 @@ import javax.inject.Inject; import javax.inject.Singleton; -import rx.Observable; -import rx.functions.Func1; +import io.reactivex.Observable; +import io.reactivex.ObservableSource; +import io.reactivex.annotations.NonNull; +import io.reactivex.functions.Function; import uk.co.ribot.androidboilerplate.data.local.DatabaseHelper; import uk.co.ribot.androidboilerplate.data.local.PreferencesHelper; import uk.co.ribot.androidboilerplate.data.model.Ribot; @@ -33,9 +35,10 @@ public PreferencesHelper getPreferencesHelper() { public Observable syncRibots() { return mRibotsService.getRibots() - .concatMap(new Func1, Observable>() { + .concatMap(new Function, ObservableSource>() { @Override - public Observable call(List ribots) { + public ObservableSource apply(@NonNull List ribots) + throws Exception { return mDatabaseHelper.setRibots(ribots); } }); diff --git a/app/src/main/java/uk/co/ribot/androidboilerplate/data/SyncService.java b/app/src/main/java/uk/co/ribot/androidboilerplate/data/SyncService.java index 4f9080f3..4789caad 100644 --- a/app/src/main/java/uk/co/ribot/androidboilerplate/data/SyncService.java +++ b/app/src/main/java/uk/co/ribot/androidboilerplate/data/SyncService.java @@ -9,9 +9,10 @@ import javax.inject.Inject; -import rx.Observer; -import rx.Subscription; -import rx.schedulers.Schedulers; +import io.reactivex.Observer; +import io.reactivex.annotations.NonNull; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; import timber.log.Timber; import uk.co.ribot.androidboilerplate.BoilerplateApplication; import uk.co.ribot.androidboilerplate.data.model.Ribot; @@ -22,7 +23,7 @@ public class SyncService extends Service { @Inject DataManager mDataManager; - private Subscription mSubscription; + private Disposable mDisposable; public static Intent getStartIntent(Context context) { return new Intent(context, SyncService.class); @@ -49,25 +50,29 @@ public int onStartCommand(Intent intent, int flags, final int startId) { return START_NOT_STICKY; } - RxUtil.unsubscribe(mSubscription); - mSubscription = mDataManager.syncRibots() + RxUtil.dispose(mDisposable); + mDataManager.syncRibots() .subscribeOn(Schedulers.io()) .subscribe(new Observer() { @Override - public void onCompleted() { - Timber.i("Synced successfully!"); - stopSelf(startId); + public void onSubscribe(@NonNull Disposable d) { + mDisposable = d; + } + + @Override + public void onNext(@NonNull Ribot ribot) { } @Override - public void onError(Throwable e) { + public void onError(@NonNull Throwable e) { Timber.w(e, "Error syncing."); stopSelf(startId); - } @Override - public void onNext(Ribot ribot) { + public void onComplete() { + Timber.i("Synced successfully!"); + stopSelf(startId); } }); @@ -76,7 +81,7 @@ public void onNext(Ribot ribot) { @Override public void onDestroy() { - if (mSubscription != null) mSubscription.unsubscribe(); + if (mDisposable != null) mDisposable.dispose(); super.onDestroy(); } @@ -98,4 +103,4 @@ public void onReceive(Context context, Intent intent) { } } -} \ No newline at end of file +} diff --git a/app/src/main/java/uk/co/ribot/androidboilerplate/data/local/DatabaseHelper.java b/app/src/main/java/uk/co/ribot/androidboilerplate/data/local/DatabaseHelper.java index fd9d52ad..80440bdf 100644 --- a/app/src/main/java/uk/co/ribot/androidboilerplate/data/local/DatabaseHelper.java +++ b/app/src/main/java/uk/co/ribot/androidboilerplate/data/local/DatabaseHelper.java @@ -2,9 +2,10 @@ import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; +import android.support.annotation.VisibleForTesting; -import com.squareup.sqlbrite.BriteDatabase; -import com.squareup.sqlbrite.SqlBrite; +import com.squareup.sqlbrite2.BriteDatabase; +import com.squareup.sqlbrite2.SqlBrite; import java.util.Collection; import java.util.List; @@ -12,10 +13,13 @@ import javax.inject.Inject; import javax.inject.Singleton; -import rx.Observable; -import rx.Subscriber; -import rx.functions.Func1; -import rx.schedulers.Schedulers; +import io.reactivex.Observable; +import io.reactivex.ObservableEmitter; +import io.reactivex.ObservableOnSubscribe; +import io.reactivex.Scheduler; +import io.reactivex.annotations.NonNull; +import io.reactivex.functions.Function; +import io.reactivex.schedulers.Schedulers; import uk.co.ribot.androidboilerplate.data.model.Ribot; @Singleton @@ -25,8 +29,13 @@ public class DatabaseHelper { @Inject public DatabaseHelper(DbOpenHelper dbOpenHelper) { + this(dbOpenHelper, Schedulers.io()); + } + + @VisibleForTesting + public DatabaseHelper(DbOpenHelper dbOpenHelper, Scheduler scheduler) { SqlBrite.Builder briteBuilder = new SqlBrite.Builder(); - mDb = briteBuilder.build().wrapDatabaseHelper(dbOpenHelper, Schedulers.immediate()); + mDb = briteBuilder.build().wrapDatabaseHelper(dbOpenHelper, scheduler); } public BriteDatabase getBriteDb() { @@ -34,10 +43,10 @@ public BriteDatabase getBriteDb() { } public Observable setRibots(final Collection newRibots) { - return Observable.create(new Observable.OnSubscribe() { + return Observable.create(new ObservableOnSubscribe() { @Override - public void call(Subscriber subscriber) { - if (subscriber.isUnsubscribed()) return; + public void subscribe(ObservableEmitter emitter) throws Exception { + if (emitter.isDisposed()) return; BriteDatabase.Transaction transaction = mDb.newTransaction(); try { mDb.delete(Db.RibotProfileTable.TABLE_NAME, null); @@ -45,10 +54,10 @@ public void call(Subscriber subscriber) { long result = mDb.insert(Db.RibotProfileTable.TABLE_NAME, Db.RibotProfileTable.toContentValues(ribot.profile()), SQLiteDatabase.CONFLICT_REPLACE); - if (result >= 0) subscriber.onNext(ribot); + if (result >= 0) emitter.onNext(ribot); } transaction.markSuccessful(); - subscriber.onCompleted(); + emitter.onComplete(); } finally { transaction.end(); } @@ -59,9 +68,9 @@ public void call(Subscriber subscriber) { public Observable> getRibots() { return mDb.createQuery(Db.RibotProfileTable.TABLE_NAME, "SELECT * FROM " + Db.RibotProfileTable.TABLE_NAME) - .mapToList(new Func1() { + .mapToList(new Function() { @Override - public Ribot call(Cursor cursor) { + public Ribot apply(@NonNull Cursor cursor) throws Exception { return Ribot.create(Db.RibotProfileTable.parseCursor(cursor)); } }); diff --git a/app/src/main/java/uk/co/ribot/androidboilerplate/data/remote/RibotsService.java b/app/src/main/java/uk/co/ribot/androidboilerplate/data/remote/RibotsService.java index e73d09c0..96050fed 100644 --- a/app/src/main/java/uk/co/ribot/androidboilerplate/data/remote/RibotsService.java +++ b/app/src/main/java/uk/co/ribot/androidboilerplate/data/remote/RibotsService.java @@ -5,11 +5,11 @@ import java.util.List; +import io.reactivex.Observable; import retrofit2.Retrofit; -import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory; +import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory; import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.http.GET; -import rx.Observable; import uk.co.ribot.androidboilerplate.data.model.Ribot; import uk.co.ribot.androidboilerplate.util.MyGsonTypeAdapterFactory; @@ -31,7 +31,7 @@ public static RibotsService newRibotsService() { Retrofit retrofit = new Retrofit.Builder() .baseUrl(RibotsService.ENDPOINT) .addConverterFactory(GsonConverterFactory.create(gson)) - .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) + .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build(); return retrofit.create(RibotsService.class); } diff --git a/app/src/main/java/uk/co/ribot/androidboilerplate/ui/base/BaseActivity.java b/app/src/main/java/uk/co/ribot/androidboilerplate/ui/base/BaseActivity.java index 280500fc..41452e1d 100644 --- a/app/src/main/java/uk/co/ribot/androidboilerplate/ui/base/BaseActivity.java +++ b/app/src/main/java/uk/co/ribot/androidboilerplate/ui/base/BaseActivity.java @@ -1,10 +1,9 @@ package uk.co.ribot.androidboilerplate.ui.base; import android.os.Bundle; +import android.support.v4.util.LongSparseArray; import android.support.v7.app.AppCompatActivity; -import java.util.HashMap; -import java.util.Map; import java.util.concurrent.atomic.AtomicLong; import timber.log.Timber; @@ -23,7 +22,8 @@ public class BaseActivity extends AppCompatActivity { private static final String KEY_ACTIVITY_ID = "KEY_ACTIVITY_ID"; private static final AtomicLong NEXT_ID = new AtomicLong(0); - private static final Map sComponentsMap = new HashMap<>(); + private static final LongSparseArray + sComponentsMap = new LongSparseArray<>(); private ActivityComponent mActivityComponent; private long mActivityId; @@ -36,16 +36,15 @@ protected void onCreate(Bundle savedInstanceState) { // being called after a configuration change. mActivityId = savedInstanceState != null ? savedInstanceState.getLong(KEY_ACTIVITY_ID) : NEXT_ID.getAndIncrement(); - ConfigPersistentComponent configPersistentComponent; - if (!sComponentsMap.containsKey(mActivityId)) { + + ConfigPersistentComponent configPersistentComponent = sComponentsMap.get(mActivityId, null); + + if (configPersistentComponent == null) { Timber.i("Creating new ConfigPersistentComponent id=%d", mActivityId); configPersistentComponent = DaggerConfigPersistentComponent.builder() .applicationComponent(BoilerplateApplication.get(this).getComponent()) .build(); sComponentsMap.put(mActivityId, configPersistentComponent); - } else { - Timber.i("Reusing ConfigPersistentComponent id=%d", mActivityId); - configPersistentComponent = sComponentsMap.get(mActivityId); } mActivityComponent = configPersistentComponent.activityComponent(new ActivityModule(this)); } diff --git a/app/src/main/java/uk/co/ribot/androidboilerplate/ui/main/MainPresenter.java b/app/src/main/java/uk/co/ribot/androidboilerplate/ui/main/MainPresenter.java index 8db33222..77a356ac 100644 --- a/app/src/main/java/uk/co/ribot/androidboilerplate/ui/main/MainPresenter.java +++ b/app/src/main/java/uk/co/ribot/androidboilerplate/ui/main/MainPresenter.java @@ -4,10 +4,11 @@ import javax.inject.Inject; -import rx.Subscriber; -import rx.Subscription; -import rx.android.schedulers.AndroidSchedulers; -import rx.schedulers.Schedulers; +import io.reactivex.Observer; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.annotations.NonNull; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; import timber.log.Timber; import uk.co.ribot.androidboilerplate.data.DataManager; import uk.co.ribot.androidboilerplate.data.model.Ribot; @@ -19,7 +20,7 @@ public class MainPresenter extends BasePresenter { private final DataManager mDataManager; - private Subscription mSubscription; + private Disposable mDisposable; @Inject public MainPresenter(DataManager dataManager) { @@ -34,34 +35,40 @@ public void attachView(MainMvpView mvpView) { @Override public void detachView() { super.detachView(); - if (mSubscription != null) mSubscription.unsubscribe(); + if (mDisposable != null) mDisposable.dispose(); } public void loadRibots() { checkViewAttached(); - RxUtil.unsubscribe(mSubscription); - mSubscription = mDataManager.getRibots() + RxUtil.dispose(mDisposable); + mDataManager.getRibots() .observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()) - .subscribe(new Subscriber>() { + .subscribe(new Observer>() { @Override - public void onCompleted() { + public void onSubscribe(@NonNull Disposable d) { + mDisposable = d; } @Override - public void onError(Throwable e) { - Timber.e(e, "There was an error loading the ribots."); - getMvpView().showError(); - } - - @Override - public void onNext(List ribots) { + public void onNext(@NonNull List ribots) { if (ribots.isEmpty()) { getMvpView().showRibotsEmpty(); } else { getMvpView().showRibots(ribots); } } + + @Override + public void onError(@NonNull Throwable e) { + Timber.e(e, "There was an error loading the ribots."); + getMvpView().showError(); + } + + @Override + public void onComplete() { + + } }); } diff --git a/app/src/main/java/uk/co/ribot/androidboilerplate/util/NetworkUtil.java b/app/src/main/java/uk/co/ribot/androidboilerplate/util/NetworkUtil.java index 08b72fa3..55fde098 100644 --- a/app/src/main/java/uk/co/ribot/androidboilerplate/util/NetworkUtil.java +++ b/app/src/main/java/uk/co/ribot/androidboilerplate/util/NetworkUtil.java @@ -4,7 +4,7 @@ import android.net.ConnectivityManager; import android.net.NetworkInfo; -import retrofit2.adapter.rxjava.HttpException; +import retrofit2.HttpException; public class NetworkUtil { diff --git a/app/src/main/java/uk/co/ribot/androidboilerplate/util/RxEventBus.java b/app/src/main/java/uk/co/ribot/androidboilerplate/util/RxEventBus.java index 1788906b..0ee3af5b 100644 --- a/app/src/main/java/uk/co/ribot/androidboilerplate/util/RxEventBus.java +++ b/app/src/main/java/uk/co/ribot/androidboilerplate/util/RxEventBus.java @@ -3,8 +3,9 @@ import javax.inject.Inject; import javax.inject.Singleton; -import rx.Observable; -import rx.subjects.PublishSubject; +import io.reactivex.BackpressureStrategy; +import io.reactivex.Flowable; +import io.reactivex.subjects.PublishSubject; /** * A simple event bus built with RxJava @@ -12,6 +13,7 @@ @Singleton public class RxEventBus { + private final BackpressureStrategy mBackpressureStrategy = BackpressureStrategy.BUFFER; private final PublishSubject mBusSubject; @Inject @@ -29,15 +31,16 @@ public void post(Object event) { /** * Observable that will emmit everything posted to the event bus. */ - public Observable observable() { - return mBusSubject; + public Flowable observable() { + return mBusSubject.toFlowable(mBackpressureStrategy); } /** * Observable that only emits events of a specific class. * Use this if you only want to subscribe to one type of events. */ - public Observable filteredObservable(final Class eventClass) { - return mBusSubject.ofType(eventClass); + public Flowable filteredObservable(final Class eventClass) { + return mBusSubject.ofType(eventClass).toFlowable(mBackpressureStrategy); } -} \ No newline at end of file + +} diff --git a/app/src/main/java/uk/co/ribot/androidboilerplate/util/RxUtil.java b/app/src/main/java/uk/co/ribot/androidboilerplate/util/RxUtil.java index c314bb55..57b0587f 100644 --- a/app/src/main/java/uk/co/ribot/androidboilerplate/util/RxUtil.java +++ b/app/src/main/java/uk/co/ribot/androidboilerplate/util/RxUtil.java @@ -1,12 +1,13 @@ package uk.co.ribot.androidboilerplate.util; -import rx.Subscription; +import io.reactivex.disposables.Disposable; public class RxUtil { - public static void unsubscribe(Subscription subscription) { - if (subscription != null && !subscription.isUnsubscribed()) { - subscription.unsubscribe(); + public static void dispose(Disposable disposable) { + if (disposable != null && !disposable.isDisposed()) { + disposable.dispose(); } } + } diff --git a/app/src/test/java/uk/co/ribot/androidboilerplate/DataManagerTest.java b/app/src/test/java/uk/co/ribot/androidboilerplate/DataManagerTest.java index 71a0ac4e..b9ab46e0 100644 --- a/app/src/test/java/uk/co/ribot/androidboilerplate/DataManagerTest.java +++ b/app/src/test/java/uk/co/ribot/androidboilerplate/DataManagerTest.java @@ -10,8 +10,8 @@ import java.util.Arrays; import java.util.List; -import rx.Observable; -import rx.observers.TestSubscriber; +import io.reactivex.Observable; +import io.reactivex.observers.TestObserver; import uk.co.ribot.androidboilerplate.data.DataManager; import uk.co.ribot.androidboilerplate.data.local.DatabaseHelper; import uk.co.ribot.androidboilerplate.data.local.PreferencesHelper; @@ -51,10 +51,10 @@ public void syncRibotsEmitsValues() { TestDataFactory.makeRibot("r2")); stubSyncRibotsHelperCalls(ribots); - TestSubscriber result = new TestSubscriber<>(); + TestObserver result = new TestObserver<>(); mDataManager.syncRibots().subscribe(result); result.assertNoErrors(); - result.assertReceivedOnNext(ribots); + result.assertValueSequence(ribots); } @Test @@ -74,7 +74,7 @@ public void syncRibotsDoesNotCallDatabaseWhenApiFails() { when(mMockRibotsService.getRibots()) .thenReturn(Observable.>error(new RuntimeException())); - mDataManager.syncRibots().subscribe(new TestSubscriber()); + mDataManager.syncRibots().subscribe(new TestObserver()); // Verify right calls to helper methods verify(mMockRibotsService).getRibots(); verify(mMockDatabaseHelper, never()).setRibots(ArgumentMatchers.anyList()); @@ -85,7 +85,7 @@ private void stubSyncRibotsHelperCalls(List ribots) { when(mMockRibotsService.getRibots()) .thenReturn(Observable.just(ribots)); when(mMockDatabaseHelper.setRibots(ribots)) - .thenReturn(Observable.from(ribots)); + .thenReturn(Observable.fromIterable(ribots)); } } diff --git a/app/src/test/java/uk/co/ribot/androidboilerplate/DatabaseHelperTest.java b/app/src/test/java/uk/co/ribot/androidboilerplate/DatabaseHelperTest.java index 1a9716d5..3247d4a1 100644 --- a/app/src/test/java/uk/co/ribot/androidboilerplate/DatabaseHelperTest.java +++ b/app/src/test/java/uk/co/ribot/androidboilerplate/DatabaseHelperTest.java @@ -2,6 +2,7 @@ import android.database.Cursor; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -12,7 +13,7 @@ import java.util.Arrays; import java.util.List; -import rx.observers.TestSubscriber; +import io.reactivex.observers.TestObserver; import uk.co.ribot.androidboilerplate.data.local.DatabaseHelper; import uk.co.ribot.androidboilerplate.data.local.Db; import uk.co.ribot.androidboilerplate.data.local.DbOpenHelper; @@ -30,22 +31,28 @@ @Config(constants = BuildConfig.class, sdk = DefaultConfig.EMULATE_SDK) public class DatabaseHelperTest { - private final DatabaseHelper mDatabaseHelper = - new DatabaseHelper(new DbOpenHelper(RuntimeEnvironment.application)); - @Rule public final RxSchedulersOverrideRule mOverrideSchedulersRule = new RxSchedulersOverrideRule(); + private DatabaseHelper mDatabaseHelper; + + @Before + public void setup() { + if (mDatabaseHelper == null) + mDatabaseHelper = new DatabaseHelper(new DbOpenHelper(RuntimeEnvironment.application), + mOverrideSchedulersRule.getScheduler()); + } + @Test public void setRibots() { Ribot ribot1 = TestDataFactory.makeRibot("r1"); Ribot ribot2 = TestDataFactory.makeRibot("r2"); List ribots = Arrays.asList(ribot1, ribot2); - TestSubscriber result = new TestSubscriber<>(); + TestObserver result = new TestObserver<>(); mDatabaseHelper.setRibots(ribots).subscribe(result); result.assertNoErrors(); - result.assertReceivedOnNext(ribots); + result.assertValueSequence(ribots); Cursor cursor = mDatabaseHelper.getBriteDb() .query("SELECT * FROM " + Db.RibotProfileTable.TABLE_NAME); @@ -64,10 +71,10 @@ public void getRibots() { mDatabaseHelper.setRibots(ribots).subscribe(); - TestSubscriber> result = new TestSubscriber<>(); + TestObserver> result = new TestObserver<>(); mDatabaseHelper.getRibots().subscribe(result); result.assertNoErrors(); result.assertValue(ribots); } -} \ No newline at end of file +} diff --git a/app/src/test/java/uk/co/ribot/androidboilerplate/MainPresenterTest.java b/app/src/test/java/uk/co/ribot/androidboilerplate/MainPresenterTest.java index 5ade5372..947ff2af 100644 --- a/app/src/test/java/uk/co/ribot/androidboilerplate/MainPresenterTest.java +++ b/app/src/test/java/uk/co/ribot/androidboilerplate/MainPresenterTest.java @@ -12,7 +12,7 @@ import java.util.Collections; import java.util.List; -import rx.Observable; +import io.reactivex.Observable; import uk.co.ribot.androidboilerplate.data.DataManager; import uk.co.ribot.androidboilerplate.data.model.Ribot; import uk.co.ribot.androidboilerplate.test.common.TestDataFactory; diff --git a/app/src/test/java/uk/co/ribot/androidboilerplate/util/RxEventBusTest.java b/app/src/test/java/uk/co/ribot/androidboilerplate/util/RxEventBusTest.java index 5e24700d..02767e79 100644 --- a/app/src/test/java/uk/co/ribot/androidboilerplate/util/RxEventBusTest.java +++ b/app/src/test/java/uk/co/ribot/androidboilerplate/util/RxEventBusTest.java @@ -4,7 +4,7 @@ import org.junit.Rule; import org.junit.Test; -import rx.observers.TestSubscriber; +import io.reactivex.subscribers.TestSubscriber; public class RxEventBusTest { diff --git a/app/src/test/java/uk/co/ribot/androidboilerplate/util/RxSchedulersOverrideRule.java b/app/src/test/java/uk/co/ribot/androidboilerplate/util/RxSchedulersOverrideRule.java index c3a729d1..7cbf44ce 100644 --- a/app/src/test/java/uk/co/ribot/androidboilerplate/util/RxSchedulersOverrideRule.java +++ b/app/src/test/java/uk/co/ribot/androidboilerplate/util/RxSchedulersOverrideRule.java @@ -3,34 +3,37 @@ import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; +import java.util.concurrent.Callable; -import rx.Scheduler; -import rx.android.plugins.RxAndroidPlugins; -import rx.android.plugins.RxAndroidSchedulersHook; -import rx.functions.Func1; -import rx.plugins.RxJavaHooks; -import rx.schedulers.Schedulers; +import io.reactivex.Scheduler; +import io.reactivex.android.plugins.RxAndroidPlugins; +import io.reactivex.annotations.NonNull; +import io.reactivex.functions.Function; +import io.reactivex.plugins.RxJavaPlugins; +import io.reactivex.schedulers.Schedulers; /** - * This rule registers SchedulerHooks for RxJava and RxAndroid to ensure that subscriptions - * always subscribeOn and observeOn Schedulers.immediate(). + * This rule registers Handlers for RxJava and RxAndroid to ensure that subscriptions + * always subscribeOn and observeOn Schedulers.trampoline(). * Warning, this rule will reset RxAndroidPlugins and RxJavaPlugins before and after each test so * if the application code uses RxJava plugins this may affect the behaviour of the testing method. */ public class RxSchedulersOverrideRule implements TestRule { - private final RxAndroidSchedulersHook mRxAndroidSchedulersHook = new RxAndroidSchedulersHook() { - @Override - public Scheduler getMainThreadScheduler() { - return Schedulers.immediate(); - } - }; + private final Function, Scheduler> mRxAndroidSchedulersHook = + new Function, Scheduler>() { + @Override + public Scheduler apply(@NonNull Callable schedulerCallable) + throws Exception { + return getScheduler(); + } + }; - private final Func1 mRxJavaImmediateScheduler = - new Func1() { + private final Function mRxJavaImmediateScheduler = + new Function() { @Override - public Scheduler call(Scheduler scheduler) { - return Schedulers.immediate(); + public Scheduler apply(@NonNull Scheduler scheduler) throws Exception { + return getScheduler(); } }; @@ -39,18 +42,23 @@ public Statement apply(final Statement base, Description description) { return new Statement() { @Override public void evaluate() throws Throwable { - RxAndroidPlugins.getInstance().reset(); - RxAndroidPlugins.getInstance().registerSchedulersHook(mRxAndroidSchedulersHook); + RxAndroidPlugins.reset(); + RxAndroidPlugins.setInitMainThreadSchedulerHandler(mRxAndroidSchedulersHook); - RxJavaHooks.reset(); - RxJavaHooks.setOnIOScheduler(mRxJavaImmediateScheduler); - RxJavaHooks.setOnNewThreadScheduler(mRxJavaImmediateScheduler); + RxJavaPlugins.reset(); + RxJavaPlugins.setIoSchedulerHandler(mRxJavaImmediateScheduler); + RxJavaPlugins.setNewThreadSchedulerHandler(mRxJavaImmediateScheduler); base.evaluate(); - RxAndroidPlugins.getInstance().reset(); - RxJavaHooks.reset(); + RxAndroidPlugins.reset(); + RxJavaPlugins.reset(); } }; } + + public Scheduler getScheduler() { + return Schedulers.trampoline(); + } + } diff --git a/build.gradle b/build.gradle index c92601fa..39332980 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { maven { url 'https://maven.fabric.io/public' } } dependencies { - classpath 'com.android.tools.build:gradle:3.0.0-beta4' + classpath 'com.android.tools.build:gradle:3.0.0' classpath 'com.github.triplet.gradle:play-publisher:1.2.0' //noinspection GradleDynamicVersion classpath 'io.fabric.tools:gradle:1.+' @@ -21,6 +21,6 @@ allprojects { } task wrapper(type: Wrapper) { - gradleVersion = '3.1' + gradleVersion = '4.1' distributionUrl = distributionUrl.replace("bin", "all") } From 9aebdb6a1eb608afedd0f00bb192202dfab22ae0 Mon Sep 17 00:00:00 2001 From: Deepankar Date: Fri, 10 Nov 2017 20:28:25 +0530 Subject: [PATCH 3/3] Added proguard rule for retrofit 2.3.0. --- app/proguard-rules.pro | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 527d4d9b..ac45820c 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -36,6 +36,8 @@ -dontnote retrofit2.Platform$IOS$MainThreadExecutor # Platform used when running on Java 8 VMs. Will not be used at runtime. -dontwarn retrofit2.Platform$Java8 +# Since 2.3.0 +-dontwarn javax.annotation.** # Retain generic type information for use by reflection by converters and adapters. -keepattributes Signature # Retain declared checked exceptions for use by a Proxy instance.