capability-push/src/
└── main/
├── AndroidManifest.xml # Android 清单文件(权限声明)
└── java/
└── com/narutohuo/xindazhou/push/
├── api/ # API 接口层
│ └── PushService.kt # 推送服务接口定义
├── factory/ # 工厂类层
│ └── PushServiceFactory.kt # 服务工厂(统一入口,单例获取)
├── impl/ # 实现层
│ └── PushServiceImpl.kt # 推送服务具体实现(封装极光推送SDK)
├── receiver/ # 接收器层
│ └── JPushReceiver.kt # 推送消息接收器(完全封装在模块内部)
├── mapping/ # 页面映射层
│ └── ActivityMapping.kt # 静态页面映射配置(支持应用未启动时跳转)
└── model/ # 数据模型层
├── PushConfig.kt # 推送服务配置模型
└── PushResponse.kt # 推送相关的数据模型
├── PushMessage # 推送消息模型
└── PushResponse # 推送响应模型
PushService 接口,包含初始化、别名/标签设置、消息监听、注册/注销等方法PushServiceFactory 单例工厂PushService 接口的具体逻辑PushServiceImpl 单例实现类JPushReceiver BroadcastReceiverAndroidManifest.xml 中自动注册,业务层无需处理ActivityMapping)自动处理通知点击跳转,支持应用未启动场景ActivityMapping 静态配置类pageMappings 参数)PushConfig - 推送服务配置模型PushMessage - 推送消息模型(标题、内容、扩展数据等)PushResponse - 推送响应模型(成功/失败、错误信息等)ActivityMapping)确保应用未启动时也能正常跳转IPushService 接口(位于 com.narutohuo.xindazhou.core.push)IPushService 接口,并通过 @Route(path = "/push/service") 注册到 ARouterARouter.getInstance().navigation(IPushService::class.java) 获取服务实例✅ SDK 依赖已添加
jpush-5.9.0.aar - 极光推送SDK(本地 AAR)jcore-5.2.0.aar - 极光推送核心库(本地 AAR)cn.jiguang.sdk.plugin:xiaomi:5.9.0 - 小米通道cn.jiguang.sdk.plugin:huawei:5.9.0 - 华为通道cn.jiguang.sdk.plugin:oppo:5.9.0 - OPPO通道cn.jiguang.sdk.plugin:vivo:5.9.0 - vivo通道cn.jiguang.sdk.plugin:meizu:5.9.0 - 魅族通道✅ 代码实现已完成
PushServiceImpl 已实现极光推送 SDK 调用,并实现 IPushService 接口PushServiceImpl 已通过 ARouter 注册(@Route(path = "/push/service"))PushServiceFactory 已创建,内部使用 ARouter 获取服务IPushService 接口已在 base-core 模块定义PushConfig 配置模型已创建JPushReceiver 消息接收器已封装ActivityMapping 静态页面映射已实现:支持应用未启动时的跳转✅ 配置已完成
capability-push 模块中管理AndroidManifest.xml 已在 capability-push/src/main/AndroidManifest.xml 中配置strings.xml 已在 capability-push/src/main/res/values/strings.xml 中配置在各厂商开放平台申请参数,并在 capability-push/src/main/res/values/strings.xml 中配置。
详细步骤请参考:厂商通道接入说明.md
所有配置都在 capability-push/src/main/res/values/strings.xml 中管理
编辑 capability-push/src/main/res/values/strings.xml:
<resources>
<!-- 极光推送基础配置(必填) -->
<string name="jpush_app_key">您的极光推送 AppKey</string>
<string name="push_jpush_channel">developer-default</string>
<!-- 厂商通道配置(可选,但推荐配置以提升推送到达率) -->
<!-- 详细配置请参考 厂商通道接入说明.md -->
</resources>
方式1:使用静态配置(推荐)
在 capability-push/src/main/java/com/narutohuo/xindazhou/push/mapping/ActivityMapping.kt 中配置:
package com.narutohuo.xindazhou.push.mapping
import com.narutohuo.xindazhou.core.log.ILog
/**
* 静态页面映射配置
*
* 优势:
* - 支持应用未启动时的跳转
* - 不依赖 Application.onCreate() 的执行顺序
* - 更可靠,避免初始化时序问题
*/
object ActivityMapping {
/**
* 静态页面映射配置
* 页面名称 -> Activity 完整类名
*/
private val pageToActivityMap = mapOf(
"detail" to "com.narutohuo.xindazhou.ui.DetailActivity",
"home" to "com.narutohuo.xindazhou.ui.MainActivity",
"order" to "com.narutohuo.xindazhou.ui.OrderActivity",
// 添加更多页面映射...
)
/**
* 根据页面名称获取 Activity Class
*
* @param page 页面名称(从推送的 extras["page"] 获取)
* @return Activity Class,如果未找到返回 null
*/
fun getActivityClass(page: String): Class<*>? {
val className = pageToActivityMap[page] ?: return null
return try {
Class.forName(className)
} catch (e: ClassNotFoundException) {
ILog.e("ActivityMapping", "找不到 Activity: $className", e)
null
}
}
}
方式2:使用运行时配置(向后兼容)
在 Application.onCreate() 中通过 pageMappings 参数配置(见下方"4. 在 Application 中初始化")。
推荐使用方式1(静态配置),因为:
在您的 XinDaZhouApplication 类中初始化推送服务:
// app/src/main/java/com/narutohuo/xindazhou/XinDaZhouApplication.kt
package com.narutohuo.xindazhou
import android.app.Application
import com.narutohuo.xindazhou.push.factory.PushServiceFactory
class XinDaZhouApplication : Application() {
override fun onCreate() {
super.onCreate()
// ========== 初始化推送服务(从资源文件读取配置)==========
// 方式1:只使用静态配置(推荐,已在 ActivityMapping 中配置)
PushServiceFactory.init(
context = this
)
// 方式2:同时配置运行时映射(可选,作为静态配置的补充)
PushServiceFactory.init(
context = this,
// 页面映射规则(用于自动跳转,作为静态配置的补充)
// 注意:如果已在 ActivityMapping 中配置,这里可以不传
pageMappings = mapOf(
"detail" to DetailActivity::class.java, // 详情页
"home" to MainActivity::class.java, // 首页
)
)
}
}
配置说明:
ActivityMapping 中的配置优先级最高,即使应用未启动也能使用pageMappings 参数作为补充,用于动态配置或覆盖静态配置pageMappings,也能正常工作(但应用未启动时可能失败)优势:
PushServiceFactory.init() 统一初始化✅ 不需要我们处理,系统自动显示
✅ 跳转逻辑已完全封装在模块内部!
工作原理:
extras["page"]ActivityMapping 获取 Activity Class(支持应用未启动场景)pageMappingsextras 参数自动传递给目标 Activity优势:
Application.onCreate()pageMappings服务器推送格式:
{
"notification": {
"title": "新订单",
"alert": "您有一个新订单待处理"
},
"extras": {
"page": "detail", // 必须匹配 ActivityMapping 或 pageMappings 中的 key
"id": "12345" // 会自动传递给目标 Activity
}
}
✅ 极光推送 SDK 会自动识别设备类型,无需手动处理!
// 方式1:只使用静态配置(推荐,支持应用未启动场景)
// 页面映射已在 ActivityMapping 中配置
PushServiceFactory.init(
context = this
)
// 方式2:同时配置运行时映射(可选,作为静态配置的补充)
PushServiceFactory.init(
context = this,
messageListener = { message ->
// 处理自定义消息(透传消息)
Timber.d("收到推送: ${message.title} - ${message.content}")
},
notificationClickListener = { message ->
// 处理通知点击事件(可选,用于统计、埋点等)
Timber.d("用户点击通知,已自动跳转")
},
pageMappings = mapOf(
"detail" to DetailActivity::class.java,
// 注意:如果已在 ActivityMapping 中配置,这里可以不传
)
)
// capability-push/src/main/java/com/narutohuo/xindazhou/push/mapping/ActivityMapping.kt
package com.narutohuo.xindazhou.push.mapping
import com.narutohuo.xindazhou.core.log.ILog
object ActivityMapping {
private val pageToActivityMap = mapOf(
"detail" to "com.narutohuo.xindazhou.ui.DetailActivity",
"home" to "com.narutohuo.xindazhou.ui.MainActivity",
"order" to "com.narutohuo.xindazhou.ui.OrderActivity",
// 添加更多页面映射...
)
fun getActivityClass(page: String): Class<*>? {
val className = pageToActivityMap[page] ?: return null
return try {
Class.forName(className)
} catch (e: ClassNotFoundException) {
ILog.e("ActivityMapping", "找不到 Activity: $className", e)
null
}
}
}
val pushService = PushServiceFactory.getInstance()
pushService.setAlias("user123") // 设置别名(可选)
pushService.setTags(listOf("vip", "premium")) // 设置标签(可选)
val registrationId = pushService.getRegistrationId() // 获取注册ID(可选)
val isEnabled = pushService.isPushEnabled() // 检查推送状态(可选)
自定义消息(透传消息):messageListener
通知消息(系统通知栏):
ActivityMapping)自动跳转,支持应用未启动场景(已封装)⚠️ 重要:所有配置都在 capability-push 模块中管理,app 模块不需要任何配置!
capability-push/src/main/res/values/strings.xmlcapability-push/src/main/AndroidManifest.xmlApplication 中调用 PushServiceFactory.init() 即可❌ 禁止在 app 模块中配置:
app/src/main/AndroidManifest.xml 中配置极光推送的 meta-dataapp/src/main/res/values/strings.xml 中配置极光推送参数app/build.gradle 中配置极光推送相关参数capability-push 模块中!A: 可以! 使用静态配置(ActivityMapping)后,即使应用从未启动过,点击通知也能正常跳转。
原理:
BroadcastReceiver 是独立组件,系统会在应用未启动时启动应用进程Application.onCreate() 的执行A:
静态配置(ActivityMapping):
运行时配置(pageMappings):
Application.onCreate() 的执行推荐:优先使用静态配置,运行时配置作为补充。
A: 在 ActivityMapping.kt 的 pageToActivityMap 中添加新的映射关系:
private val pageToActivityMap = mapOf(
"detail" to "com.narutohuo.xindazhou.ui.DetailActivity",
"newPage" to "com.narutohuo.xindazhou.ui.NewPageActivity", // 新增
)
注意:Activity 类名必须是完整的包名路径。
A: 静态配置(ActivityMapping)优先级更高。如果静态配置中找到了对应的 Activity,会优先使用静态配置;如果静态配置中未找到,才会使用运行时配置(pageMappings)。