ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Android安卓保活sdk

Android安卓保活sdk Android 后台存活率提升实战从被厂商杀到推送稳定送达Android 7–16T e l e g r a m \textcolor{red}{Telegram}Telegram:lily059开篇先别急着写代码“我的应用在小米上被杀得妈都不认识在华为上活不过两小时。”这句抱怨我在评论区看过太多次。但大多数人在动手之前其实连自己的进程是被谁杀的都不知道——于是开始堆各种保活奇技淫巧最后既没解决问题还把自己送进了应用市场的审核黑名单。这篇文章不讲玄学只讲三件事用系统 API定位真实死因而不是猜系统允许你做的合规且有效的手段以及各自的适用边界哪些做法是红线——技术上能用但会带来审核、合规和卸载率的代价。一、先分清 5 种死法进程被杀不是一件事是五件事。搞错病因药就不可能对。类型触发者典型表现能否用合规手段缓解LMK低内存杀手内核内存吃紧时按 oom_adj 依次回收可以降低自身占用、提升 oom_adj 优先级后台执行限制Android 8 框架后台startService()抛IllegalStateException隐式广播收不到可以前台服务、显式广播、WorkManagerDoze / App Standby系统省电息屏静置后网络、闹钟、任务被延迟可以setExactAndAllowWhileIdle、电池优化白名单厂商省电策略MIUI / EMUI / ColorOS / Funtouch…锁屏后清后台、自启动被拦、关联启动被禁部分可以引导用户开白名单无法代码绕过用户强停 / 划掉卡片用户最近任务划掉、设置里点强制停止不应该缓解——这是用户的明确意图最后一行请记住用户强停是用户的权利不是 bug。后面会专门讲为什么去对抗它是笔亏本买卖。二、用ApplicationExitInfo定位死因这是本文最有价值的一段Android 11API 30之后系统提供了官方接口查询进程历史退出原因别再靠我猜是 MIUI 杀的了。RequiresApi(Build.VERSION_CODES.R)fundumpExitReasons(context:Context){valamcontext.getSystemService(Context.ACTIVITY_SERVICE)asActivityManager// 参数packageName(传 null 表示自己)、maxNum、maxNum 上限am.getHistoricalProcessExitReasons(null,0,20).forEach{info-Log.i(ExitInfo, time${info.timestamp}reason${info.reason.toReadable()}importance${info.importance}// 被杀时的前台/后台状态desc${info.description?:-}rss${info.rss}// 峰值内存排查 LMK 很有用pss${info.pss}.trimIndent())// 如果是崩溃/ANR还能拿到 traceinfo.traceInputStream?.use{/* 交给崩溃平台解析 */}}}RequiresApi(Build.VERSION_CODES.R)funInt.toReadable():Stringwhen(this){ApplicationExitInfo.REASON_LOW_MEMORY-LMK 内存不足被杀ApplicationExitInfo.REASON_USER_REQUESTED-用户主动结束/强停ApplicationExitInfo.REASON_OTHER-系统回收(厂商策略常见)ApplicationExitInfo.REASON_FREEZER-被系统冻结后回收(Android 12)ApplicationExitInfo.REASON_ANR-ANRApplicationExitInfo.REASON_CRASH-Java 崩溃ApplicationExitInfo.REASON_CRASH_NATIVE-Native 崩溃ApplicationExitInfo.REASON_EXCESSIVE_RESOURCE_USAGE-资源占用超限被回收ApplicationExitInfo.REASON_DEPENDENCY_DIED-依赖进程退出连带ApplicationExitInfo.REASON_INITIALIZATION_FAILURE-启动初始化失败else-其他($this)}怎么读这些数据大量REASON_LOW_MEMORY→ 你的常驻内存太大先做内存优化别急着加服务大量REASON_OTHER/REASON_FREEZER→ 大概率是厂商策略属于引导用户开白名单的场景REASON_USER_REQUESTED占比高 →停下来想想产品体验用户在用脚投票REASON_CRASH*/REASON_ANR→ 先修 bug崩溃的进程谈何存活。小提示这套 API 在部分 OEM ROM 上粒度有限REASON_OTHER占比会偏高。配合进程启动时间 前后台切换时间点一起埋点才能还原完整链路。三、合规且有效的手段按场景选型3.1 前台服务首选但类型必须选对Android 14API 34起foregroundServiceType是强制项且必须声明对应的FOREGROUND_SERVICE_*权限否则直接崩溃。uses-permissionandroid:nameandroid.permission.FOREGROUND_SERVICE/uses-permissionandroid:nameandroid.permission.FOREGROUND_SERVICE_DATA_SYNC/serviceandroid:name.SyncServiceandroid:exportedfalseandroid:foregroundServiceTypedataSync/overridefunonStartCommand(intent:Intent?,flags:Int,startId:Int):Int{startForeground(NOTIFY_ID,buildNotification(),// 必须用户可见别做成透明通知ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC// Android 10 可显式指定)returnSTART_STICKY}几个必须知道的边界类型不是随便选的dataSync用于数据同步mediaPlayback用于播放location用于导航——选错类型在市场审核时会被打回Android 15 起dataSync/mediaProcessing类型的前台服务有24 小时内累计 6 小时的时长上限超时会收到onTimeout()回调必须在那里收尾别装作没看见从后台启动前台服务有限制Android 12 收紧了 exception 列表Android 15 起SYSTEM_ALERT_WINDOW也不再是豁免理由。想靠悬浮窗权限换后台起服务的老套路已经不通了。3.2 推送通道真正决定消息能不能到的是它如果你的诉求是消息别丢那么长连接和推送通道的权重远高于进程存活。进程被杀后能被推送拉起比死撑进程省电得多。海外老老实实用FCM国内接入厂商推送小米、华为 HMS、OPPO、vivo、荣耀、魅族是硬需求——这些通道在应用被杀后仍可送达而且不需要你保活需要自建长连接时做好断线重连退避、心跳与厂商通道的互补在线走长连接离线走推送。一句话能用推送解决的不要用保活解决。3.3 WorkManager可延迟任务的正确姿势valrequestPeriodicWorkRequestBuilderSyncWorker(15,TimeUnit.MINUTES).setBackoffCriteria(BackoffPolicy.EXPONENTIAL,10,TimeUnit.MINUTES).build()WorkManager.getInstance(context).enqueueUniquePeriodicWork(sync,ExistingPeriodicWorkPolicy.KEEP,request)周期任务最小间隔 15 分钟别指望它做秒级轮询ExistingPeriodicWorkPolicy.KEEP避免每次启动都重建任务WorkManager保证会执行但不保证准时受 Doze / 电池策略影响对时效敏感就别用它。3.4 精确闹钟注意 Android 12/13 的权限变化valamcontext.getSystemService(AlarmManager::class.java)valtriggerAtSystem.currentTimeMillis()5*60_000valcanExactif(Build.VERSION.SDK_INTBuild.VERSION_CODES.S){am.canScheduleExactAlarms()// Android 12 必须运行时判断}elsetrueif(canExact){am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,triggerAt,pendingIntent)}else{// 降级为不精确闹钟同样能穿透 Doze只是时间有偏差am.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,triggerAt,pendingIntent)}权限上有两个坑SCHEDULE_EXACT_ALARMAndroid 12用户可撤销必须运行时判断canScheduleExactAlarms()USE_EXACT_ALARMAndroid 13仅限闹钟、日历等以精确时间为核心功能的应用Google Play 有明确的用途审核别拿来当免申请精确闹钟的后门。3.5 电池优化白名单能要但要说清为什么valpmcontext.getSystemService(PowerManager::class.java)if(!pm.isIgnoringBatteryOptimizations(packageName)){// 先给用户一个为什么的说明页再跳转转化率会高很多startActivity(Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).setData(Uri.parse(package:$packageName)))}注意Google Play 对REQUEST_IGNORE_BATTERY_OPTIMIZATIONS的使用场景有白名单限制报警、VoIP 等滥用会被下架。要在隐私政策与商店说明里写清楚用途。3.6 厂商自启动 / 后台白名单没有统一 API只能好好引导这是国内场景绕不开的一环但要接受一个现实没有稳定、官方支持的跳转接口。各家设置路径都不同MIUI 自启动、华为应用启动管理、OPPO/vivo后台高耗电、三星未监控的应用…写死厂商 Activity 的做法会随 ROM 版本失效稳妥做法先try/catch尝试跳转失败就兜底到本应用详情页让用户自己找到开关// 兜底方案永远不会失效startActivity(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).setData(Uri.parse(package:$packageName)))更好的做法是在 App 内做图文引导机型识别 截图指引比直接甩一个系统设置页有效得多。3.7 如果是真有硬件用CompanionDeviceManager应用确实要长期和 BLE 设备手环、车机、健康设备保持连接时Android 12 的CompanionDeviceService是官方为你准备的正当方案系统会给予后台运行豁免。前提是你真的有配对设备。为了保活伪造一个 BLE 关联既过不了审核也拿不到系统信任。3.8 系统绑定服务功能必须匹配NotificationListenerService、AccessibilityService、DeviceAdminService、VpnService都能带来极高的进程优先级但它们都有强烈的用途契约通知监听 → 你要真的做通知聚合/过滤无障碍 → 你要真的有辅助功能否则属高危Play 会重点审查VPN → 你要真的做流量处理而不是建一个 127.0.0.1 的回环隧道DeviceAdmin → 你要真的是企业设备管理场景。为了保活而申请是这个领域最常见的自杀行为要么审核不过要么被用户投诉后下架。四、明确劝退的反模式红线下面这些在技术上都做得到但我不建议你在任何要上架的产品里使用理由写在后面。反模式为什么不要做1 像素 / 透明 Activity 拉活违反 Android 10 后台启动 Activity 限制莫名弹出是用户投诉与欺骗行为判定的高发点播放无声音频抢占音频焦点、显著增加耗电部分 ROM 直接判定异常进程空 SyncAdapter / 空账户 只为触发同步账户与同步必须有真实用途属审核重点双进程 / 空进程互拉Android 8 后台服务限制下已基本失效且明确被视为滥用滥用 MediaStyle / CallStyle 绕过POST_NOTIFICATIONS这是绕过权限管控与 Android 13 的通知权限设计初衷冲突风险极高反射隐藏 API、直调 AMS、“防强停”用户在设置里点强制停止是明确意图对抗它更高的卸载率 市场审核风险am instrument拉活滥用测试框架属明确异常行为需要特别说明防强停这类方案在某些灰色场景如靠后台复活刷广告曝光里被当作卖点但对正经产品它是负资产——你对抗的是掏钱买你服务的用户赢了一次强停输掉的是留存和口碑。合规上还有一条通用红线Google Play 的Device and Network Abuse、Foreground Service 政策以及国内各应用市场的后台行为规范都会对上述行为做拦截或下架处理。五、落地指标 选型表5.1 建议埋点的指标指标采集方式用来判断进程退出原因分布ApplicationExitInfo死因构成方向对不对前后台切换时间点onTrimMemory(TRIM_MEMORY_UI_HIDDEN)/ProcessLifecycleOwner被杀时是否在后台冷启动次数 / 日启动埋点去重存活率最直观的代理指标推送到达率推送平台侧数据最终业务指标比存活率更重要前台服务时长与超时次数onTimeout()回调Android 15 时长限制是否踩线5.2 场景 → 方案场景推荐组合IM / 社交消息厂商推送 前台服务dataSync WorkManager 兜底音乐 / 播客播放前台服务mediaPlayback MediaSession真播放时导航 / 运动轨迹前台服务location 精准闹钟IoT / BLE 外设CompanionDeviceService 前台服务企业设备管理Device Owner DeviceAdminService天气 / 资讯定时刷新WorkManager15 分钟 闹钟 / 提醒类精确闹钟 USE_EXACT_ALARM符合政策前提六、上线前检查清单已用ApplicationExitInfo统计过真实死因分布且方向与数据匹配前台服务类型选对、FOREGROUND_SERVICE_*权限齐全、通知用户可见Android 15 时长限制场景已实现onTimeout()收尾已完成 FCM / 厂商推送接入消息链路不依赖进程活着精确闹钟做了canScheduleExactAlarms()判断与降级电池优化白名单、自启动引导均有用途说明且跳转有兜底未使用第四节表格里的任何反模式隐私政策、商店说明与申请的权限一一对应真机矩阵覆盖小米 / 华为 / OPPO / vivo / 三星 / 原生结语后台存活率这件事核心不是堆多少种保活手段而是用对系统给你的那把钥匙把消息交给推送通道把可延迟任务交给 WorkManager把持续工作交给带正确类型的前台服务把系统限制的边界用引导和授权去沟通——而不是去绕过它。你的机型上有遇到过REASON_OTHER特别高的死亡姿势吗欢迎在评论区贴出你的exitReason分布一起看看是谁在动手。
返回列表