Work manager do not run when proguarding app in api 27,28,29

2k Views Asked by At

I have a periodic task that runs every 15 minutes.

When proguarding the application. The work manager does not work if the app is killed from the background.

Testing devices : One plus 7T, Nokia 5+ ,Google pixel 2 Emulator

The work manager only gets executed if app is either in the foreground or is in the background.

Disabling the proguard Work manager works in all 3 condition

  1. The app is in foreground

  2. The App in background

  3. The app is killed from the background

As per the raised issue by me on https://issuetracker.google.com/issues/160492142#

There might be issue in proguard file.

 #noinspection ShrinkerUnresolvedReference
 -keepattributes *Annotation*
 -keepattributes SourceFile,LineNumberTable
 # prevent Crashlytics obfuscation
 -keep class com.crashlytics.** { *; }
 -dontwarn com.crashlytics.**
 
 
 -keep public class * extends java.lang.Exception
 -keep class com.google.android.gms.measurement.AppMeasurement { *; }
 
 
 ###################################################################################################
 
 # Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and
 # EnclosingMethod is required to use InnerClasses.
 -keepattributes Signature, InnerClasses, EnclosingMethod
 
 # Retrofit does reflection on method and parameter annotations.
 -keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations
 
 # Retain service method parameters when optimizing.
 -keepclassmembers,allowshrinking,allowobfuscation interface * {
     @retrofit2.http.* <methods>; }
 
 
 -keepclassmembers,allowobfuscation class * {   @com.squareup.moshi.Json <fields>; }
 # Ignore annotation used for build tooling.
 -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
 
 # Ignore JSR 305 annotations for embedding nullability information.
 -dontwarn javax.annotation.**
 
 # Guarded by a NoClassDefFoundError try/catch and only used when on the classpath.
 -dontwarn kotlin.Unit
 
 # Top-level functions that can only be used by Kotlin.
 -dontwarn retrofit2.KotlinExtensions
 -dontwarn retrofit2.KotlinExtensions$*
 
 # With R8 full mode, it sees no subtypes of Retrofit interfaces since they are created with a Proxy
 # and replaces all potential values with null. Explicitly keeping the interfaces prevents this.
 -if interface * { @retrofit2.http.* <methods>; }
 -keep,allowobfuscation interface <1>
 # Retrofit does reflection on method and parameter annotations.
 
 ###################################################################################################
 -keep class com.example.app.data.retrofit.**{ *; }
 
 ########################################OKHTTP#####################################################
 
 # JSR 305 annotations are for embedding nullability information.
 #-dontwarn javax.annotation.**
 
 # A resource is loaded with a relative path so the package of this class must be preserved.
 -keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
 
 # Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java.
 -dontwarn org.codehaus.mojo.animal_sniffer.*
 
 # OkHttp platform used only on JVM and when Conscrypt dependency is available.
 -dontwarn okhttp3.internal.platform.ConscryptPlatform
 
 ###################################################################################################
 
 
 #-keepattributes Annotation
 #-keepattributes Signature,RuntimeVisibleAnnotations,AnnotationDefault
 #-keepattributes *Annotation*
 #-keepclassmembers enum androidx.lifecycle.Lifecycle.Event {
 #    <fields>;
 #}
 #-keep !interface * implements androidx.lifecycle.LifecycleObserver {
 #}
 #-keep class * implements androidx.lifecycle.GeneratedAdapter {
 #    <init>(...);
 #}
 
 ##noinspection ShrinkerUnresolvedReference
 #-keepclassmembers class android.arch.** { *; }
 #-keep class android.arch.** { *; }
 #-dontwarn android.arch.**
implementation "androidx.work:work-runtime:2.4.0-rc01"

I have tried all the versions. But the same issue is there. It doesn't work in Api Level 27,28,29.

Work manager work correctly in all the older API level's

Doesn't means it does not work only when app is killed.

It works when app is in the foreground and when app is in the background.

Work manager is been initialize manually in application class

 public void setWorker() {
        Constraints constraints = new Constraints.Builder()
                .setRequiredNetworkType(NetworkType.CONNECTED)
                .build();
   
        PeriodicWorkRequest myWork =
                new PeriodicWorkRequest.
                        Builder(AppWorker.class,
                        15, TimeUnit.MINUTES, 5, TimeUnit.MINUTES)
                        .addTag("app_periodic")
                        .setConstraints(constraints)
                       .build();

            try {

            WorkManager.getInstance(MyApplication.this)
                    .enqueueUniquePeriodicWork("app_worker_notify", ExistingPeriodicWorkPolicy.KEEP, myWork);

        } catch (IllegalStateException e) {
            e.printStackTrace();
        }
    }

Sample Code

https://github.com/parmarravi/WorkManagerSample

update as of 11-07-2020

A detailed study on this issue.

Android Studio Work Manager Strange behaviour

1

There are 1 best solutions below

0
Ravi Parmar On

This happened due to battery optimization by various vendors this day. You need to disable the optimization and your work manager will work like a charm!!

 private void checkBatteryOptimization(){

        PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (pm != null && !pm.isIgnoringBatteryOptimizations(getPackageName())) {
                AlertBottomSheetFragment alertBottomSheetFragment = AlertBottomSheetFragment.newInstance();
                alertBottomSheetFragment.setData("For Timely notifications please disable battery optimization for Your App", new AlertBottomSheetImpl() {
                    @Override
                    public void acceptAlertBottom() {
                        askIgnoreOptimization();
                    }

                    @Override
                    public void declineAlertBottom() {

                    }
                });
                alertBottomSheetFragment.show(getSupportFragmentManager(), FRAG_BOTTOM_SHEET_ALERT_TAG);

            } else {
                // already ignoring battery optimization code here next you want to do
                Timber.i("already ignoring battery optimization code here next you want to do");
            }
        } else {
            Timber.i("version below");
            // already ignoring battery optimization code here next you want to do
        }
    }

    private void askIgnoreOptimization() {

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
            intent.setData(Uri.parse("package:" + getPackageName()));
            startActivityForResult(intent, IGNORE_BATTERY_OPTIMIZATION_REQUEST);
        }
    }