在 api 27、28、29 中保护应用程序时,工作管理器不运行

Posted

技术标签:

【中文标题】在 api 27、28、29 中保护应用程序时,工作管理器不运行【英文标题】:Work manager do not run when proguarding app in api 27,28,29 【发布时间】:2020-10-29 14:22:12 【问题描述】:

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

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

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

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

禁用 proguard 工作管理器在所有 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 级别中都能正常工作

并不意味着只有在应用被杀死时才不起作用

当应用程序在前台和应用程序在后台时,它都有效。

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

 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 年 7 月 11 日起更新

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

Android Studio Work Manager Strange behaviour

【问题讨论】:

您是否在清单中声明了后台任务权限? 是的..仍然无法正常工作 在你提供的谷歌线程中,问题是在混淆的 gson 模型中,那个人试图从后台工作中反序列化一些东西,仔细检查你在工作中做了什么,也许你做了一些不能很好地工作的反思混淆? 尝试用一些琐碎的东西替换作业逻辑,例如只是打印一些东西到控制台 试过了,但同样的问题正在发生。问题是当应用程序在前台或后台时工作管理器工作,但是当您终止应用程序时,工作管理器停止工作。此外,Android Studio 4.0 也存在问题。工作经理没有按预期工作。 【参考方案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);
        
    

【讨论】:

以上是关于在 api 27、28、29 中保护应用程序时,工作管理器不运行的主要内容,如果未能解决你的问题,请参考以下文章

OAuth2/OpenID Connect 保护 API 的自动化 API 测试

在烧瓶中保护 REST api

使用 keycloak 保护节点 js 后端 API

在 Android Studio 中运行 AVD 时应用程序崩溃。我正在使用 API 27 在虚拟设备像素 5x 上运行

为公共客户端使用 cookie 保护 Web API 的陷阱

我想将我的应用程序目标sdk版本29降级到28,google play控制台可以允许吗?