WorkManager Data.Builder does not support Parcelable

前端 未结 6 1202
心在旅途
心在旅途 2021-02-20 06:18

When you have a big POJO with loads of variables (Booleans, Int, Strings) and you want to use the new Work Manager to start a job. You then create a Data file which gets added t

6条回答
  •  你的背包
    2021-02-20 06:55

    I'm posting my solution here as I think it might be interesting for other people. Note that this was my first go at it, I am well aware that we could probably improve upon it, but this is a nice start.

    Start by declaring an abstract class that extends from Worker like this:

    abstract class SingleParameterWorker : Worker(), WorkManagerDataExtender{
    
        final override fun doWork(): WorkerResult {
            return doWork(inputData.getParameter(getDefaultParameter()))
        }
    
        abstract fun doWork(t: T): WorkerResult
    
        abstract fun getDefaultParameter(): T
    }
    

    The WorkManagerDataExtender is an interface that has extensions to Data. getParameter() is one of these extensions:

     fun  Data.getParameter(defaultValue: T): T {
        return when (defaultValue) {
            is ClassA-> getClassA() as T
            is ClassB-> getClassB() as T
            ...
            else -> defaultValue
        }
    }
    

    Unfortunately I was not able to use the power of inlined + reified to avoid all the default value logic. If someone can, let me know in the comments. getClassA() and getClassB() are also extensions on the same interface. Here is an example of one of them:

    fun Data.getClassA(): ClassA {
            val map = keyValueMap
            return ClassA(map["field1"] as String,
                    map["field2"] as Int,
                    map["field3"] as String,
                    map["field4"] as Long,
                    map["field5"] as String)
        }
    
    fun ClassA.toMap(): Map {
            return mapOf("field1" to field1,
                    "field2" to field2,
                    "field3" to field3,
                    "field4" to field4,
                    "field5" to field5)
        }
    

    (Then you can call toWorkData() on the return of this extension, or make it return Data instead, but this way you can add more key value pairs to the Map before calling toWorkData()

    And there you go, now all you have to do is create subclasses of the SingleParameterWorker and then create "to" and "from" extensions to Data to whatever class you need. In my case since I had a lot of Workers that needed the same type of POJO, it seemed like a nice solution.

提交回复
热议问题