跳到主要内容

设计推送系统

问题

Android 客户端推送系统如何设计?

答案

推送方案对比

方案覆盖范围到达率省电适用场景
FCM海外Google Play 应用
厂商推送(小米/华为/OPPO/vivo)国内国内各厂商设备
自建长连接全部即时通讯
轮询全部不推荐

国内推送架构

统一推送 SDK 设计

// 统一推送接口
interface PushProvider {
fun register(context: Context)
fun unregister(context: Context)
fun getToken(): String?
}

// 小米推送实现
class XiaomiPushProvider : PushProvider {
override fun register(context: Context) {
MiPushClient.registerPush(context, APP_ID, APP_KEY)
}
override fun getToken(): String? = MiPushClient.getRegId(context)
override fun unregister(context: Context) { /* ... */ }
}

// 华为推送实现
class HuaweiPushProvider : PushProvider { /* ... */ }

// 推送管理器:根据设备自动选择
object PushManager {
private lateinit var provider: PushProvider

fun init(context: Context) {
provider = when {
isHuaweiDevice() -> HuaweiPushProvider()
isXiaomiDevice() -> XiaomiPushProvider()
isOppoDevice() -> OppoPushProvider()
isVivoDevice() -> VivoPushProvider()
else -> SelfBuildPushProvider() // 兜底方案
}
provider.register(context)
}

// 统一上报 Token 到业务服务端
fun onTokenReceived(token: String, channel: String) {
api.reportPushToken(token, channel, deviceId)
}
}

消息处理

// 统一消息回调
class UnifiedPushReceiver {
fun onMessageReceived(message: PushMessage) {
when (message.type) {
MessageType.NOTIFICATION -> {
// 系统通知栏展示
showNotification(message)
}
MessageType.TRANSPARENT -> {
// 透传消息(静默处理)
handleTransparentMessage(message)
}
}
}

private fun showNotification(message: PushMessage) {
val intent = DeepLinkHelper.parse(message.deepLink)
val notification = NotificationCompat.Builder(context, channelId)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(message.title)
.setContentText(message.body)
.setContentIntent(PendingIntent.getActivity(
context, 0, intent,
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
))
.build()
notificationManager.notify(message.id.hashCode(), notification)
}
}

常见面试问题

Q1: 为什么国内不用 FCM?

答案

FCM(Firebase Cloud Messaging)依赖 Google Play Services,国内大部分 Android 设备没有预装 GMS(Google Mobile Services),无法使用 FCM。因此国内采用各厂商自有的推送通道(小米推送、华为 HMS Push、OPPO Push、vivo Push),这些推送通道由厂商系统进程常驻保活,到达率高且省电。

Q2: 如何保证推送的到达率?

答案

  1. 多通道冗余:厂商推送 + 自建长连接双通道,互为兜底
  2. 推送回执:客户端收到推送后上报回执,服务端未收到回执的消息通过其他通道重发
  3. 离线消息:用户上线时拉取未读消息列表,补偿推送丢失
  4. 通知权限引导:引导用户开启通知权限,避免被系统拦截

相关链接