How to pass own class into Worker in android?
Asked Answered
V

3

24

How can we pass Serializable object in work manager by setData method of work manager? Is there any way to process with Work manager by passing object?

WorkManager is a library used to enqueue work that is guaranteed to execute after its constraints are met. WorkManager allows observation of work status and the ability to create complex chains of work.

 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();

It crash app and showing error like AddressBookData is not valid class.

Note: I want to pass POJO class in work manager and get InputData from work manager in doWork Method.

Via answered 25/6, 2018 at 7:32 Comment(10)
share your code.Expansionism
@HemantParmar Edited Question please see.Kill
share your AddressBookData class.Expansionism
@HemantParmar You can consider any pojo class with implements Serializable.Kill
you are getting error in AddressBookData class. that's why!Expansionism
Have you work with work manager? @HemantParmarKill
I have tried by passing different POJO class in Work manager but everytime i getting this error. Have you any solution for this ?@HemantParmarKill
you didn't share both AddressBookData & DataSyncWorker class, how can i get find solution for you?Expansionism
@HemantParmar It's not possible to pass POJO class in Work manager because it supports only few data types and array to pass into Input Data.Kill
Simply convert you object to string using Gson and pass it to InputData and in worker class again convert back to your pojo object.Bod
S
15

Today, I also faced this issue. So I found the way to pass an object.

My Requirement is pass Bitmap object. (You can pass as per your requirement)

Add dependency in your Gradle file

Gradle:

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

Use the below method for serializing and de-serializing the object

 // 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);
    }

Serialize object.

 String bitmapString = Helper.serializeToJson(bmp);

Pass to the data object.

 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);

Handle your value in Worker class.

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

Now your bitmap object is ready in Worker class.

Cheers !

Sines answered 22/12, 2018 at 18:32 Comment(5)
It will be create crash when you want to upload high resolution Image and second cons is like that you have to do more process like 1.Serialize into Json and 2. Deserialize into String to . JSON and it is very complex and risky process.Kill
agree, but its one of idea how to do thisSines
In short we have to pass String only in any ways.Kill
Yes dear. But if somehow we want to pass multiple strings so better to create pojo and do above operation.Sines
This should not be the way of achieving this since the params can't exceed 10 kb in size. Otherwise it will throw an Exception.Wines
C
8

You cannot directly provide a POJO for a WorkManager. See the documentation of the Data.Builder#putAll method:

Valid types are: Boolean, Integer, Long, Double, String, and array versions of each of those types.

If possible, you may serialize your POJO. For example, if it is truly small and simple, you can use JSON to encode it to string and then decode it in the Worker.

However, for more complicated classes, I personally store them in the database (SQLite, Room) and then just pass the primary key of the given object. The Worker then fetches the object from the database. However, in my experience that can be usually avoided.

Cuff answered 4/7, 2018 at 18:1 Comment(3)
Yeah we can do it but i from Db i fetch array and from arraylist i want to pass perticular pojo class and do process in work manager. Yea i already implemented this but if Work manager in direclty supports Serializable class than i want to checkKill
And there's no way to pass other object instances as well because the data will be internally serialized/deserialized to and from a byte array using ObjectOutputStream and ObjectInputStream. Even though it's possible to write a serializable instance there, Google only allowed primitive types.Oakes
My architecture requires me to pass a shared instance to my static Worker to call some methods on that instance. I have no other option but to use a singleton; very ugly.Oakes
D
0

WorkManager allows only these types - Byte, Integer, Long, Boolean,Double , String, Float and array of these types. Otherwise it will throw IllegalArgumentException This is the internal implementation of Data class -

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));
                }
Dendroid answered 22/5, 2022 at 10:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.