使用WorkManager上传大型位图

3

我正在尝试使用WorkManager将位图上传到服务器。基本上,用户拍照并按下按钮将其上传到服务器。

然而,问题出现在我尝试使用Work Manager的Data.Builder类序列化位图时,该类有10240字节的限制。因此,如果我执行以下操作:

val data = Data.Builder()
//Add parameter in Data class. just like bundle. You can also add Boolean and Number in parameter.
data.putString(IMAGE_NAME, identifier)
data.putByteArray(BITMAP_ARRAY, imageBytes) 

以下崩溃将被抛出:java.lang.IllegalStateException: 数据在序列化时不能占用超过10240字节 我可以在启动工作管理器之前将照片保存到文件中,在工作管理器中读取该文件。但如果可能的话,我宁愿避免所有文件管理,因为用户可能会关闭应用程序等。
如果服务器响应成功,我只想要保存文件。
有没有其他方法可以实现这一点?是否有Google针对这种情况的“建议”?
这是我的doWork()的WorkManager功能。
    override fun doWork(): Result {
        val identifier = inputData.getString(IMAGE_NAME)!!
        val imageBytes = inputData.getByteArray(BITMAP_ARRAY)!!

        val result = executeRequest(identifier, imageBytes)

        return if (result.isSuccess()) {
            //saving image
            val bitmap = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
            saveToInternalStorage(context, identifier, bitmap)
            Result.success()
        } else {
            Result.failure()
        }
    }
2个回答

4
我希望尽可能避免所有文件管理,因为用户随时可以关闭应用程序等。

那么您就不应该使用WorkManager。 文档 明确说明了这一点:

WorkManager不适用于可安全终止的进程内后台工作,如果应用程序进程消失

关于在 Data 中放置大量数据,文档 也很明确:

Data对象的最大大小限制为10KB。[...]如果您需要在Worker之间传输更多数据,则应将数据放在其他位置

因此,如果您仍然想使用WorkManager进行此操作(我认为这是个好主意),则必须将大型位图放入文件中,将该文件的URI放入Data对象中,然后在您的doWork()中从该文件上传位图,然后删除该文件。

如果在doWork()执行过程中杀死了应用程序,WorkManager框架将稍后(具有逐渐增加的退避时间)启动您的应用程序进程(没有UI),并尝试再次上传。

如果应用程序无法发送或关闭,将其保存在文件中以便稍后发送是有意义的。但是,在这种情况下,文件管理始终必须存在,因为例如强制关闭,对吧? 我的意思是,我将不得不在每次应用程序启动时检查临时文件是否已经存在,并且工作没有被调度,对吧? - Luis Pereira
1
使用例如 UUID.randomUUID().toString() 为每个作业创建唯一的文件名。然后在文件上传和删除后,仅从 doWork() 返回 Result.success()。由于 WorkManager 的保证,不需要在应用程序启动期间检查是否有任何文件剩余要上传。 - Enselic

1

我将图像保存到文件系统中,然后在我的数据对象中传递了文件路径。在我的工作类内部,通过检索我创建数据对象时传递的文件路径来上传图像。


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