保活状态我们知道Android系统会杀后台进程,而且随着系统版本的更新,杀进程的力度会越来越大。系统本身的出发点是好的,因为可以节省内存,降低功耗,避免一些流氓行为。但是对于一些应用来说,应用本身的使用场景需要在后台运行,用户也愿意让它在后台运行,比如运行应用。流氓软件一方面使用各种流氓手段保活,另一方面系统加大后台查杀力度,导致我们一些真正需要后台运行的应用被误杀,这是悲惨的。优雅的活着?为了保活??,出现了很多“黑科技”,比如1像素Activity,播放无声音频,双进程互相守护。这些做法可以说是非常流氓,甚至破坏了安卓生态。幸运的是,随着安卓系统版本的更新,这些非常规的保活手段很多都失效了。对于那些真正需要在后台运行的应用程序,我们如何优雅地让它们保持存活呢?后台运行白名单从Android6.0开始,系统增加了休眠模式以节省电量。系统空闲一段时间后,会杀死后台运行的进程。但是系统会有一个后台运行的白名单,白名单中的应用不会受到影响。本机系统下,通过“设置”-“电池”-“电池优化”-“未优化的应用”可以看到。在白名单中,你通常会看到下面两条:下次产品说“XXX能存活,我们为什么不能!”,你就知道怎么回去了。各大厂商通过与手机厂商合作,默认将自己的应用加入白名单。如果你在大厂可以谈这种合作,就不用再找了。幸运的是,系统还没有抛弃我们,允许我们申请将应用加入白名单。首先在AndroidManifest.xml文件中配置权限:可以通过以下方法判断我们的应用是否在白名单中:@RequiresApi(api=Build.VERSION_CODES.M)privatebooleanisIgnoringBatteryOptimizations(){booleanisIgnoring=false;PowerManagerpowerManager=(PowerManager)getSystemService(Context.POWER_SERVICE);if(powerManager!=null){isIgnoring=powerManager.isIgnoringBatteryOptimizations(getPackageName());}returnisIgnoring;}如果不在白名单中,可以通过以下代码申请加入白名单:@RequiresApi(api=Build.VERSION_CODES.M)publicvoidrequestIgnoreBatteryOptimizations(){try{Intentintent=newIntent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);intent.setData(Uri.parse("package:"+getPackageName()));startActivity(intent);}catch(Exceptione){e.printStackTrace();}}应用的时候,应用上会出现一个窗口:可以看到,这个system弹窗会影响电池寿命的Reminder,所以想要用户点击权限,必须要有相关的说明。如果要判断用户是否点击了Allow,可以在申请的时候调用startActivityForResult,然后在onActivityResult中判断是否在白名单中。厂商后台管理Android开发的难点之一是各大手机厂商对原生系统进行了不同的定制,导致需要进行不同的适配。后台管理就是一个很好的例子。几乎每个制造商都有自己的后台管理。即使应用加入了后台运行白名单,仍然有可能被厂商自己的后台管理杀掉。如果能够将应用加入厂商系统的后台管理白名单,则可以进一步降低进程被杀的概率。不同的厂商在不同的地方设置,一般都是在自己的“手机管家”里,但比较难的是,即使是同一个厂商的系统,也可能在不同的地方设置不同的版本。理想的方式是我们根据不同的手机,甚至不同的系统版本,给用户呈现一个图形化的操作步骤,并提供一个按钮直接跳转到指定页面进行设置。但是需要适配各个厂商的各个版本,工作量比较大。在用真机测试了大部分主流安卓厂商的手机后,整理了部分手机的相关资料。首先我们可以定义这两个方法:/***跳转到指定应用的首页*/privatevoidshowActivity(@NonNullStringpackageName){Intentintent=getPackageManager().getLaunchIntentForPackage(packageName);startActivity(intent);}/***跳转到指定应用的指定页面*/privatevoidshowActivity(@NonNullStringpackageName,@NonNullStringactivityDir){Intentintent=newIntent();intent.setComponent(newComponentName(packageName,activityDir));intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);启动活动(意图);}以下是部分手机厂商的判断,跳转方式及对应的设置步骤。跳转方式不保证所有版本都跳转成功,需要trycatch。华为厂商判断:publicbooleanisHuawei(){if(Build.BRAND==null){returnfalse;}else{returnBuild.BRAND.toLowerCase().equals("huawei")||Build.BRAND.toLowerCase().equals("honor");}}跳转到华为手机管家的启动管理页面:}catch(Exceptione){showActivity("com.huawei.systemmanager","com.huawei.systemmanager.optimize.bootstart.BootStartActivity");}}操作步骤:应用启动管理->关闭应用开关->开启允许自我-启动小米厂商判断:publicstaticbooleanisXiaomi(){returnBuild.BRAND!=null&&Build.BRAND.toLowerCase().equals("xiaomi");}跳转到小米安全中心自启动管理页面:privatevoidgoXiaomiSetting(){showActivity("com.miui.securitycenter","com.miui.permcenter.autostart.AutoStartManagementActivity");}操作步骤:授权管理ent->自启动管理->允许应用自启动OPPO厂商判断:publicstaticbooleanisOPPO(){returnBuild.BRAND!=null&&Build.BRAND.toLowerCase().equals("oppo");}跳转到OPPO手机管家:safe");}catch(Exceptione2){try{showActivity("com.coloros.oppoguardelf");}catch(Exceptione3){showActivity("com.coloros.safecenter");}}}}操作步骤:权限隐私->自启动管理->允许应用自启动vivo厂商判断:publicstaticbooleanisVIVO(){returnBuild.BRAND!=null&&Build.BRAND.toLowerCase().equals("vivo");}跳转到vivo手机管家:privatevoidgoVIVOSetting(){showActivity("com.iqoo.secure");}操作步骤:权限管理->自启动->允许应用自启动魅族厂商判断:publicstaticbooleanisMeizu(){returnBuild.BRAND!=null&&Build.BRAND。toLowerCase().equals("meizu");}跳转到魅族手机管家:privatevoidgoMeizuSetting(){showActivity("com.meizu.safe");}操作步骤:权限管理->后台管理->ClickApp->允许后台运行三星厂商判断:publicstaticbooleanisSamsung(){returnBuild.BRAND!=null&&Build.BRAND.toLowerCase().equals("samsung");}跳转到SamsungSmartManager:privatevoidgoSamsungSetting(){try{showActivity("com.samsung.android.sm_cn");}catch(Exceptione){showActivity("com.samsung.android.sm");}}操作步骤:自动运行应用->打开应用开关->电池管理->不受监控的应用->添加应用乐视厂商判断:publicstaticbooleanisLeTV(){returnBuild.BRAND!=null&&Build.BRAND.toLowerCase().equals("letv");}跳转到乐视手机管家:privatevoidgoLetvSetting(){showActivity("com.letv.android.letvsafe","com.letv.android.letvsafe.AutobootManageActivity");}操作步骤:自启动管理->允许应用自启动Smartisan厂商判断:publicstaticbooleanisSmartisan(){returnBuild.BRAND!=null&&Build.BRAND.toLowerCase().equals("smartisan");}跳转手机管理:privatevoidgoSmartisanSetting(){showActivity("com.smartisanos.security");}操作步骤:权限管理->自启动权限离子管理->点击应用->允许系统启动向友商致敬?在我之前做的运行应用中,我在settings里面添加了一个permissionSet页面,把上面说的settings放在里面。最近,我发现我的一个朋友也跟进了。图一是我们做的,图二是我做的:我做的不够好,从设计到文案,连从十几部手机上截下来的图,一一致敬方向。谢谢大家的认可,但是最近在发布会上听到这样一句话:致敬的同时,还能说声谢谢吗?一方面说明确实存在容易被kill活的进程,另一方面这个难题也说明这种引导用户设置白名单的方法是有效的。