如何在ArrayList到达它的最后一个元素时执行代码?

时间:2017-10-02 14:05:00

标签: android for-loop arraylist firebase-realtime-database

我正在运行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?

请告诉我。

4 个答案:

答案 0 :(得分:2)

一种方法是检查回调中的计数。您可以在onFailureonSuccess中查看。像这样的东西

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循环,现在一切都按预期工作。