【发布时间】:2018-08-19 23:57:16
【问题描述】:
如何让 AsyncTask 的 doInBackground() 仅在另一个异步方法完成时返回?
在高层次上,活动的目的是允许用户上传评论。评论也可能有图像。现在在我的代码中,我有两个 AsyncTask:ImageCompressionTask 和 ImageUploadTask。基本上,一旦用户选择要上传的图像,就会为每个图像执行ImageCompressionTask。在该任务的onPostExecute() 方法中,ImageUploadTask 被执行。 ImageUploadTask 的目的是上传压缩图片,并使用上述上传图片的下载 URL 更新 Firestore(数据库)。以下是它的代码:
public class ImageUploadTask extends AsyncTask<byte[], Integer, Void> {
@Override
protected Void doInBackground(byte[]... bytes) {
StorageReference ref = App.getFireStorage().getReference();
ref = ref.child("review_images/" +
mDestinationId + "/" +
mExistingReview.getReviewId() + "/" +
mUploadProgressCount);
ref.putBytes(bytes[0]).addOnSuccessListener(taskSnapshot -> {
String url = taskSnapshot.getDownloadUrl().toString();
mExistingReview.getImages().add(url);
App.getFirestore().collection("reviews").document(mExistingReview.getReviewId()).set(mExistingReview);
mUploadProgressCount++;
});
return null;
}
}
但是,问题在于doInBackground() 过早返回。我明白为什么会发生这种情况(因为 ref.putBytes() 方法异步运行)但我希望它等到 ref.putBytes() 完成。我该怎么做?
【问题讨论】:
-
你看过
CountDownLatch吗?这可能有用:docs.oracle.com/javase/7/docs/api/java/util/concurrent/… -
你为什么还要使用
AsyncTask?您编写的任何代码都不需要在后台线程上运行(这就是putBytes要求您设置成功侦听器的原因)。 -
@ninge 我以前没有使用过这个,但是查看文档,我是否更正假设这与 Gastón Saillén 提供的解决方案非常相似?
-
@ianhanniballake 没错,我对将网络代码放入
ImageCompressionTask的主线程犹豫不决,因此我这样做了。除了冗余之外,这种方法有什么缺点吗? -
@NajmSheikh 它应该是一个更简单的解决方案。看我的回答。
标签: android firebase android-asynctask firebase-storage