我正在运行for循环并在其中的firebase上保存数据。
这是我的代码:
private int counter = 1;
pProgress.setMessage("Posting...");
pProgress.show();
pProgress.setCancelable(false);
for (int i=0; i<imageArray.size(); i++) {
Uri file = Uri.fromFile(new File(imageArray.get(i).toString()));
String key = database.getReference().push().getKey();
UploadTask uploadTask = storage.getReference().child(AccessToken.getCurrentAccessToken().getUserId()).child(key).child("product_image").putFile(file);
uploadTask.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
// Handle unsuccessful uploads
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
counter++;
if (counter == imageArray.size()) {
Toast.makeText(getBaseContext(), "successfully posted!", Toast.LENGTH_SHORT).show();
imageView.setImageResource(0);
pDescription.setText("");
pDuration.setText("");
pPrice.setText("");
label.setText("Label");
if (pProgress.isShowing()) {
pProgress.dismiss();
}
}
// taskSnapshot.getMetadata() contains file metadata such as size, content-type, and download URL.
@SuppressWarnings("VisibleForTests")
Uri downloadUrl = taskSnapshot.getDownloadUrl();
imageUrls.add(downloadUrl.toString());
database.getReference().child(AccessToken.getCurrentAccessToken().getUserId()).child(id).child("pDescription").setValue(pDescription.getText().toString());
database.getReference().child(AccessToken.getCurrentAccessToken().getUserId()).child(id).child("pDuration").setValue(pDuration.getText().toString());
database.getReference().child(AccessToken.getCurrentAccessToken().getUserId()).child(id).child("pPrice").setValue(pPrice.getText().toString());
if (imageUrls != null) {
for (int i=0; i<imageUrls.size(); i++) {
Log.d("imageUrlsSize", String.valueOf(imageUrls.size()));
String idtwo = database.getReference().push().getKey();
database.getReference().child(AccessToken.getCurrentAccessToken().getUserId()).child(id).child(idtwo).child("imageUrl").setValue(downloadUrl.toString());
if (imageUrls.size() > 0) {
imageUrls.clear();
}
}
}
}
});
}
我想显示ProgressDialog
并在成功上传数据时将其关闭。同样,我也希望清除EditText
字段和ImageView
。
如何确定imageArray
已结束,以便我可以解除ProgressDialog并清除edittext以及imageview?
请告诉我。
答案 0 :(得分:2)
一种方法是检查回调中的计数。您可以在onFailure
和onSuccess
中查看。像这样的东西
for (int i = 0; i < imageArray.size(); i++) {
final int currentCount = i + 1;
/** code **/
onSuccess() {
if (currentCount == imageArray.size()) // do something
}
}
您可能还需要声明imageArray
为最终版。这样做的缺点是您将知道最后一个元素已被处理,但您不知道是否有其他请求仍未处理。更好的方法是在您的类中使用成员字段,例如
class YourClass{ private int currentCount = 0; }
你会在你的回调中再计算一次,例如
for (int i = 0; i < imageArray.size(); i++) {
onSuccess() {
currentCount++;
if (currentCount == imageArray.size()) // do something
}
}
答案 1 :(得分:0)
Beeing a Real-time数据库没有任何时间,我们可以说我们已经从数据库加载了所有的重新调用,或者ArrayList已经到达它的最后一个元素。发生这种情况是因为有可能在每个时刻都可以改变,即可以添加或删除项目/项目。这就是构建Firebase的方式。
但是对你的问题的简短回答,首先在imageUrls
方法中移动onSuccess()
ArrayList的声明,否则由于此方法的异步行为将为null。其次,在名为count
的类中定义一个变量,并在每次调用onSuccess()
方法时增加它的值,并将其与列表的size
进行比较,如下所示:
int count = 0;
onSuccess() {
count++;
if(count == imageArray.size() : do somethig ? do something else)
}
答案 2 :(得分:0)
您正在处理异步任务,因此您需要封装作业并使用队列和回调。尝试类似的东西:
class Job{
private Runnable completeCallback;
private String key;
private Uri file;
public Job(String key, Uri file) {
this.key = key;
this.file = file;
}
public void setCompleteCallback(Runnable completeCallback) {
this.completeCallback = completeCallback;
}
void doWork(){
UploadTask uploadTask = storage.getReference().child(AccessToken.getCurrentAccessToken().getUserId()).child(key).child("product_image").putFile(file);
uploadTask.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
// Handle unsuccessful uploads
completeCallback.run();
}
}).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
// taskSnapshot.getMetadata() contains file metadata such as size, content-type, and download URL.
@SuppressWarnings("VisibleForTests")
Uri downloadUrl = taskSnapshot.getDownloadUrl();
imageUrls.add(downloadUrl.toString());
database.getReference().child(AccessToken.getCurrentAccessToken().getUserId()).child(id).child("pDescription").setValue(pDescription.getText().toString());
database.getReference().child(AccessToken.getCurrentAccessToken().getUserId()).child(id).child("pDuration").setValue(pDuration.getText().toString());
database.getReference().child(AccessToken.getCurrentAccessToken().getUserId()).child(id).child("pPrice").setValue(pPrice.getText().toString());
if (imageUrls != null) {
for (int i=0; i<imageUrls.size(); i++) {
Log.d("imageUrlsSize", String.valueOf(imageUrls.size()));
String idtwo = database.getReference().push().getKey();
database.getReference().child(AccessToken.getCurrentAccessToken().getUserId()).child(id).child(idtwo).child("imageUrl").setValue(downloadUrl.toString());
if (imageUrls.size() > 0) {
imageUrls.clear();
}
}
}
completeCallback.run();
}
});
}
}
class Queue {
ArrayList<Job> jobs = new ArrayList<>();
private int total;
public void execute(){
total = imageArray.size();
for (int i=0; i<imageArray.size(); i++) {
Uri file = Uri.fromFile(new File(imageArray.get(i).toString()));
String key = database.getReference().push().getKey();
Job job = new Job(key, file);
job.setCompleteCallback(new Runnable() {
@Override
public void run() {
jobs.remove(job);
updateUi();
}
});
jobs.add(job);
}
for (int i = jobs.size() - 1; i >= 0; i--) {
Job job = jobs.get(i);
job.doWork();
}
}
private void updateUi() {
Log.d("UI", "Completed " + jobs.size() + "/" + total);
}
}
答案 3 :(得分:0)
我在Murat K的回答的帮助下弄明白了。
我刚转移了这段代码
database.getReference().child(AccessToken.getCurrentAccessToken().getUserId()).child(id).child("pDescription").setValue(pDescription.getText().toString());
database.getReference().child(AccessToken.getCurrentAccessToken().getUserId()).child(id).child("pDuration").setValue(pDuration.getText().toString());
database.getReference().child(AccessToken.getCurrentAccessToken().getUserId()).child(id).child("pPrice").setValue(pPrice.getText().toString());
退出for
循环,现在一切都按预期工作。