如何在Android中的Work Manager中传递POJO类?

24
我们如何通过工作管理器setData方法传递Serializable对象?是否有一种方法可以通过传递对象来与WorkManager一起处理?
WorkManager是一个库,用于排队工作,并保证在满足其约束条件后执行。 WorkManager允许观察工作状态并能够创建复杂的工作链。
 Map<String, Object> map = new HashMap<>();
 AddressBookData addressBookData = new AddressBookData();
 addressBookData.setThreadId(001);

 map.put("AddressBookData", addressBookData);


 Data data = new Data.Builder()
                    .putAll(map)
                    .build();

 OneTimeWorkRequest compressionWork =
                new OneTimeWorkRequest.Builder(DataSyncWorker.class)
                        .setInputData(data)
                        .build();

它会导致应用程序崩溃,并显示类似“AddressBookData不是有效的类”的错误。

注意:我想在工作管理器中传递POJO类,并在doWork方法中从工作管理器获取InputData。


分享你的代码。 - Hemant Parmar
请分享您的AddressBookData类。 - Hemant Parmar
1
@HemantParmar 你可以考虑使用任何实现Serializable接口的POJO类。 - Vishal Patoliya ツ
1
@HemantParmar,无法在Work Manager中传递POJO类,因为它仅支持少量数据类型和数组来传递输入数据。 - Vishal Patoliya ツ
1
只需使用Gson将对象转换为字符串,然后将其传递给InputData,在worker类中再次将其转换回您的pojo对象。 - Siddhesh Shirodkar
显示剩余5条评论
3个回答

14

今天,我也遇到了这个问题。所以我找到了一种传递对象的方法。

我的需求是传递Bitmap对象。(您可以根据自己的需求传递)

在Gradle文件中添加依赖项

Gradle:

dependencies {
  implementation 'com.google.code.gson:gson:2.8.5'
}

使用以下方法对对象进行序列化和反序列化

 // Serialize a single object.
    public static String serializeToJson(Bitmap bmp) {
        Gson gson = new Gson();
        return gson.toJson(bmp);
    }

    // Deserialize to single object.
    public static Bitmap deserializeFromJson(String jsonString) {
        Gson gson = new Gson();
        return gson.fromJson(jsonString, Bitmap.class);
    }
序列化对象。
 String bitmapString = Helper.serializeToJson(bmp);

传递给数据对象。

 Data.Builder builder = new Data.Builder();
 builder.putString("bmp, bitmapString);
 Data data = builder.build();
        OneTimeWorkRequest simpleRequest = new OneTimeWorkRequest.Builder(ExampleWorker.class)
                .setInputData(data)
                .build();
        WorkManager.getInstance().enqueue(simpleRequest);

Worker 类中处理您的值。

Data data = getInputData();
String bitmapString = data.getString(NOTIFICATION_BITMAP);
Bitmap bitmap = Helper.deserializeFromJson(bitmapString);

现在你的位图对象已经在 Worker 类中准备好了。

干杯!


2
当您想上传高分辨率图像时,它会导致崩溃。第二个缺点是您需要执行更多的过程,例如1.将其序列化为Json,2.将其反序列化为字符串以进行JSON操作,这是非常复杂和有风险的过程。 - Vishal Patoliya ツ
1
同意,但这只是其中一种做法的想法。 - Yogesh Rathi
1
简而言之,我们必须以任何方式仅传递字符串。 - Vishal Patoliya ツ
2
是的亲爱的。但如果我们想要传递多个字符串,最好创建POJO并执行上述操作。 - Yogesh Rathi
1
这不应该是实现此目的的方式,因为参数大小不能超过10kb。否则会抛出异常。 - Joaquin Iurchuk

7
您不能直接为WorkManager提供POJO。请参阅Data.Builder#putAll方法的文档:https://developer.android.com/reference/androidx/work/Data.Builder.html#putAll(androidx.work.Data) 有效类型为:布尔型、整型、长整型、双精度浮点型、字符串和上述每种类型的数组版本。
如果可能的话,您可以将POJO序列化。例如,如果它非常小而简单,您可以使用JSON将其编码为字符串,然后在Worker中解码它。
但是,对于更复杂的类,我个人会将它们存储在数据库(SQLite、Room)中,然后只传递给定对象的主键。Worker然后从数据库中获取对象。但是,在我的经验中,通常可以避免这种情况。

是的,我们可以做到,但我从数据库中获取数组,然后从ArrayList中传递特定的POJO类,并在工作管理器中进行处理。是的,我已经实现了这个功能,但如果工作管理器直接支持可序列化类,那么我想要检查一下。 - Vishal Patoliya ツ
而且也没有办法传递其他对象实例,因为数据将使用“ObjectOutputStream”和“ObjectInputStream”内部序列化/反序列化为字节数组。即使可以在那里编写可序列化的实例,但Google仅允许原始类型。 - TheRealChx101
我的架构要求我将一个共享实例传递给我的静态Worker,以便调用该实例上的一些方法。我别无选择,只能使用单例模式;非常丑陋。 - TheRealChx101

0

WorkManager 只允许使用以下类型 - Byte、Integer、Long、Boolean、Double、String、Float 和这些类型的数组。否则,它将抛出 IllegalArgumentException 异常。 这是 Data 类的内部实现 -

if (value == null) {
                mValues.put(key, null);
            } else {
                Class<?> valueType = value.getClass();
                if (valueType == Boolean.class
                        || valueType == Byte.class
                        || valueType == Integer.class
                        || valueType == Long.class
                        || valueType == Float.class
                        || valueType == Double.class
                        || valueType == String.class
                        || valueType == Boolean[].class
                        || valueType == Byte[].class
                        || valueType == Integer[].class
                        || valueType == Long[].class
                        || valueType == Float[].class
                        || valueType == Double[].class
                        || valueType == String[].class) {
                    mValues.put(key, value);
                } else if (valueType == boolean[].class) {
                    mValues.put(key, convertPrimitiveBooleanArray((boolean[]) value));
                } else if (valueType == byte[].class) {
                    mValues.put(key, convertPrimitiveByteArray((byte[]) value));
                } else if (valueType == int[].class) {
                    mValues.put(key, convertPrimitiveIntArray((int[]) value));
                } else if (valueType == long[].class) {
                    mValues.put(key, convertPrimitiveLongArray((long[]) value));
                } else if (valueType == float[].class) {
                    mValues.put(key, convertPrimitiveFloatArray((float[]) value));
                } else if (valueType == double[].class) {
                    mValues.put(key, convertPrimitiveDoubleArray((double[]) value));
                } else {
                    throw new IllegalArgumentException(
                            String.format("Key %s has invalid type %s", key, valueType));
                }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接