尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

利用BroadcastReceiver实现极光推送在APP进程被杀死后的消息接收

利用BroadcastReceiver实现极光推送在APP进程被杀死后的消息接收 1. 为什么APP被杀后收不到极光推送很多Android开发者都遇到过这样的问题当APP进程被系统清理后极光推送的消息就收不到了。这个问题其实跟Android系统的进程管理机制有关。Android系统为了节省内存和电量会在后台自动清理长时间不活动的APP进程。这时候APP中运行的推送服务也会被一起终止。网上流传的解决方案中最常见的是在AndroidManifest.xml中给application设置android:persistenttrue属性。这个方法的出发点是好的想让APP变成常驻进程。但实测下来这个属性对大多数普通APP根本不起作用。因为android:persistent是系统级应用的专属属性普通APP即使用了这个属性系统也不会理会。2. BroadcastReceiver的救场方案2.1 静态注册广播接收器经过多次尝试我发现最可靠的解决方案是通过静态注册BroadcastReceiver。静态注册的特点是即使APP进程被杀死系统仍然能唤醒这个接收器。具体实现步骤如下首先创建一个继承自BroadcastReceiver的类public class PushReceiver extends BroadcastReceiver { Override public void onReceive(Context context, Intent intent) { // 重启极光推送服务 Intent pushIntent new Intent(context, PushService.class); context.startService(pushIntent); } }这个接收器的核心逻辑很简单当收到系统广播时重新启动极光推送的服务。这样就能保证推送服务在APP被杀后能自动恢复。2.2 AndroidManifest的配置关键静态注册的关键在于AndroidManifest.xml的配置。需要特别注意以下几点receiver的enabled属性要设为true必须包含极光推送的所有必要action建议添加系统广播的action作为触发器完整配置示例如下receiver android:name.PushReceiver android:enabledtrue intent-filter !-- 极光推送必需action -- action android:namecn.jpush.android.intent.REGISTRATION/ action android:namecn.jpush.android.intent.MESSAGE_RECEIVED/ action android:namecn.jpush.android.intent.NOTIFICATION_RECEIVED/ action android:namecn.jpush.android.intent.NOTIFICATION_OPENED/ action android:namecn.jpush.android.intent.CONNECTION/ !-- 系统广播action -- action android:nameandroid.intent.action.BOOT_COMPLETED/ action android:nameandroid.net.conn.CONNECTIVITY_CHANGE/ category android:name你的包名/ /intent-filter /receiver3. 实现原理深度解析3.1 广播接收器的工作机制BroadcastReceiver是Android四大组件之一它允许应用接收来自系统或其他应用发出的广播。静态注册的接收器会被系统记录在PackageManager中即使应用进程不存在系统也能直接创建新进程来运行接收器。当以下事件发生时我们的PushReceiver就会被唤醒设备开机完成网络状态发生变化极光推送服务器下发消息3.2 进程生命周期的影响Android应用进程被杀死后其中的所有组件都会随之销毁。但静态注册的BroadcastReceiver是个例外它属于粘性组件。系统会为它维护一个独立的注册表确保广播能送达。实测发现通过这种方式极光推送服务能在APP被杀后5秒内自动恢复。这个时间差对用户体验的影响很小大多数用户根本察觉不到推送曾经中断过。4. 常见问题与优化建议4.1 电量消耗的平衡虽然这个方案很有效但频繁唤醒APP确实会增加电量消耗。建议在实现时注意以下几点只在必要时处理广播在onReceive()中先判断intent的action无关广播直接返回添加适当的延迟可以使用Handler.postDelayed()让服务重启稍微延后考虑用户使用场景比如夜间可以适当降低推送频率4.2 兼容性处理不同Android版本对广播的限制有所不同Android 8.0对静态广播接收做了限制部分厂商ROM会禁用某些系统广播后台服务启动限制需要考虑针对这些情况可以在代码中添加版本判断if (Build.VERSION.SDK_INT Build.VERSION_CODES.O) { context.startForegroundService(pushIntent); } else { context.startService(pushIntent); }4.3 服务保活的替代方案除了广播接收器还有一些辅助手段可以提高推送的稳定性使用JobScheduler定期检查推送服务状态结合WorkManager实现后台任务在Application的onCreate()中检查服务状态但实测下来BroadcastReceiver方案仍然是兼容性最好、实现最简单的方案。特别是在国内各种定制ROM上这个方案的稳定性表现相当出色。
返回列表