4

我有一个每 15 分钟运行一次的定期任务。

保护应用程序时。如果应用程序从后台被杀死,工作管理器将无法工作。

测试设备:一加7T、诺基亚5+、谷歌pixel 2 Emulator

只有当应用程序处于前台或后台时,工作管理器才会被执行。

禁用 proguard 工作管理器在所有 3 个条件下工作

  1. 该应用程序在前台

  2. 后台应用程序

  3. 该应用程序从后台被杀死

根据我在https://issuetracker.google.com/issues/160492142#上提出的问题

proguard 文件中可能有问题。

 #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"

我已经尝试了所有版本。但同样的问题也存在。它在 Api 级别 27、28、29 中不起作用。

工作管理器在所有旧 API 级别中都能正常工作

并不意味着它仅在app 被杀死时才起作用

当应用程序在前台和应用程序在后台时,它可以工作。

工作管理器已在应用程序类中手动初始化

 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();
        }
    }

示例代码

https://github.com/parmarravi/WorkManagerSample

自 2020 年 11 月 7 日起更新

关于这个问题的详细研究。

Android Studio Work Manager 奇怪的行为

4

1 回答 1

1

这是由于今天各个供应商对电池进行了优化。您需要禁用优化,您的工作经理会像魅力一样工作!

 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);
        }
    }
于 2020-12-25T06:54:05.270 回答