如何将Bundle转换为WorkManager的Data对象传递推送信息?
解决Bundle转WorkManager Data的问题
当然可以搞定!因为Android O的后台限制,你要把GCM的处理从IntentService迁移到WorkManager,而遇到Bundle转Data的问题,其实只需要把Bundle里的内容逐个映射到Data支持的类型就行,具体操作看下面:
核心思路
WorkManager的Data只支持基本数据类型(String、int、long、float、boolean)以及它们的数组,不像Bundle能直接存复杂对象。所以我们要做的就是遍历Bundle里的键值对,把每个值转换成Data.Builder能接受的格式,再构建出Data对象传给WorkManager。
代码实现步骤
1. 在BroadcastReceiver中转换Bundle为Data并发起WorkRequest
override fun onReceive(context: Context?, intent: Intent?) { val pushBundle = intent?.extras ?: return // 构建Data.Builder val dataBuilder = Data.Builder() // 遍历Bundle中的所有键值对 pushBundle.keySet().forEach { key -> when (val value = pushBundle.get(key)) { // 处理基本类型 is String -> dataBuilder.putString(key, value) is Int -> dataBuilder.putInt(key, value) is Long -> dataBuilder.putLong(key, value) is Float -> dataBuilder.putFloat(key, value) is Boolean -> dataBuilder.putBoolean(key, value) // 处理数组类型 is Array<String> -> dataBuilder.putStringArray(key, value) is IntArray -> dataBuilder.putIntArray(key, value) is LongArray -> dataBuilder.putLongArray(key, value) // 处理复杂Serializable对象(转成JSON字符串) is Serializable -> { val jsonString = Gson().toJson(value) dataBuilder.putString(key, jsonString) } // 其他类型可以根据需求自行扩展转换逻辑 } } // 构建WorkRequest并加入队列 val workRequest = OneTimeWorkRequestBuilder<PushProcessingWorker>() .setInputData(dataBuilder.build()) .build() WorkManager.getInstance(context!!).enqueue(workRequest) }
2. 在Worker中读取Data并还原(可选)
在Worker里,你可以直接读取inputData里的键值对,也可以把它转回Bundle方便后续使用:
class PushProcessingWorker( context: Context, workerParams: WorkerParameters ) : Worker(context, workerParams) { override fun doWork(): Result { val inputData = inputData val processedBundle = Bundle() // 把Data转回Bundle inputData.keySet().forEach { key -> when { inputData.hasString(key) -> processedBundle.putString(key, inputData.getString(key)) inputData.hasInt(key) -> processedBundle.putInt(key, inputData.getInt(key, 0)) inputData.hasLong(key) -> processedBundle.putLong(key, inputData.getLong(key, 0L)) // 对应BroadcastReceiver中的类型,逐个还原 } } // 这里处理你的推送业务逻辑 handlePushNotification(processedBundle) return Result.success() } private fun handlePushNotification(bundle: Bundle) { // 具体的推送处理逻辑 } }
注意事项
- 大小限制:
Data的总大小不能超过10KB,如果你的Bundle里有大文件或者大量数据,建议先把数据存储到本地(比如SharedPreferences、Room或者文件),然后只把存储路径/ID传到Data中。 - 复杂对象处理:如果Bundle里有自定义对象,记得要让对象实现
Serializable或者Parcelable,然后转成JSON字符串存入Data,在Worker里再解析回来。
内容的提问来源于stack exchange,提问作者Gogi Bobina
相关产品推荐
相关产品推荐

