Android自定义库不依赖FCM如何获取外部传入的FirebaseMessaging对象
方案可行,可通过反射+运行时类型校验实现,无需工具库引入FCM依赖
核心实现逻辑
- 方法参数不直接声明
FirebaseMessaging类型,改用通用类型(Kotlin用Any?,Java用Object) - 运行时先校验传入对象的全限定类名是否为
com.google.firebase.messaging.FirebaseMessaging,不匹配直接返回空/错误 - 反射调用
FirebaseMessaging实例的令牌获取方法,拿到结果后走原有注册到自身服务器的逻辑即可 - 所有反射操作捕获异常,避免非法调用导致崩溃
具体代码实现(Kotlin示例)
/** * 无需工具库依赖FCM,自动获取FCM令牌并完成注册 * @param firebaseMessagingObj 接入方传入的FirebaseMessaging实例 * @return 成功返回FCM令牌,失败返回null */ fun detectToken(firebaseMessagingObj: Any?): String? { // 空参数直接返回 if (firebaseMessagingObj == null) return null // 校验参数类型是否合法,避免非FCM实例传入 if (firebaseMessagingObj::class.java.canonicalName != "com.google.firebase.messaging.FirebaseMessaging") { return null } return try { // 反射调用getToken()方法,返回Task<String>对象 val getTokenMethod = firebaseMessagingObj::class.java.getMethod("getToken") val tokenTask = getTokenMethod.invoke(firebaseMessagingObj) // 反射获取Task执行结果,若需要异步处理可自行反射添加OnCompleteListener监听 val getResultMethod = tokenTask::class.java.getMethod("getResult") getResultMethod.invoke(tokenTask) as? String } catch (e: Exception) { // 捕获所有反射相关异常,包括方法不存在、权限不足、调用失败等场景 null } }
版本兼容说明
如果需要兼容21.0.0以下版本的FCM SDK,需额外增加getInstanceId()方法的反射逻辑,从返回的InstanceIdResult对象中取token字段即可。
Gradle配置补充
如果需要在编译工具库时做代码校验,可在工具库的build.gradle中添加FCM的compileOnly依赖:
dependencies { // 仅编译时生效,不会打包到AAR,也不会强制接入方引入FCM compileOnly 'com.google.firebase:firebase-messaging:23.4.1' }
接入提示
你只需在文档中说明:需要使用推送功能的开发者自行在项目中引入FCM依赖,初始化后传入FirebaseMessaging.getInstance()对象调用detectToken即可;不需要推送功能的开发者完全不受影响,不会引入任何FCM相关冗余代码。
内容的提问来源于stack exchange,提问作者NapoleonTheCake
相关产品推荐
相关产品推荐

