如何在另一个异步方法完成时才让AsyncTask的doInBackground()
返回?
在较高的层面上,活动的目的是允许用户上传评论。评论也可能有图像。现在在我的代码中,我有两个AsyncTasks: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()
完成。我该怎么做?
答案 0 :(得分:2)
请你这样检查一下:
@Override
protected synchronized 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;
}
答案 1 :(得分:1)
我用ObservableInteger
是一个侦听值的侦听器
private ObservableInteger mObsInt;
//Listener
mObsInt = new ObservableInteger();
mObsInt.set(0);
mObsInt.setOnIntegerChangeListener(new OnIntegerChangeListener()
{
@Override
public void onIntegerChanged(int newValue)
{
if (mObsInt.get()==1)
Log.e("Downloads"," mObsInt 1");
Log.e("Download1"," Finished first process ");
if (mObsInt.get()==2){
Log.e("Downloads"," mObsInt 2");
Log.e("Download2"," Finished second process ");
mProgressDialog.dismiss();
Intent mainIntent = new Intent().setClass(LoginActivity.this, Principal.class);
startActivity(mainIntent);
finish();
}
}
});
然后执行此操作(在进程完成或asynctask之后)
mObsInt.set(mObsInt.get()+1);
所以它会计数,如果第一个完成的黑暗将是1,当第二个完成时,黑暗将是2,所以在黑暗== 2之后,你可以继续进行你需要的其他活动或过程< / p>
快乐的编码!
答案 2 :(得分:1)
这可以通过CountDownLatch完成:
public class ImageUploadTask extends AsyncTask<byte[], Integer, Void> {
@Override
protected Void doInBackground(byte[]... bytes) {
// Initialize CountDownLatch
final CountDownLatch signal = new CountDownLatch(1);
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++;
// Start count down
signal.countDown();
});
// Wait for putBytes to return and handle case if
// threads get interrupted.
// You can also specify a maximum time to wait before
// displaying error to user (ie Try Again)
try {
signal.await(30, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
}