У меня есть массив файлов URI, и я загружаю их в хранилище Firebase с циклом for. Следуя документации, я могу получить URL-адрес загрузки, реализующий методы continueWithTask
и addOnCompleteListener
UploadTask
объекта UploadTask
, поэтому я пытаюсь сохранить все URL- UploadTask
внутри массива. Моя проблема в том, что массив, который я использую для сохранения URL-адреса, пуст, но изображения загружаются в папку хранилища firestore после вычисления кода, вероятно, потому что continueWithTask
и addOnCompleteListener
являются асинхронными методами.
Как я могу решить это?
for (int i = 0; i < photos.size(); i++) {
mStorage=FirebaseStorage.getInstance().getReference().child("images/" + j);
mUploadTask=mStorage.putFile(photos.get(i));
Task<Uri>urlTask = uploadTask.continueWithTask(new Continuation<UploadTask.TaskSnapshot, Task<Uri>>() {
@Override
public Task<Uri> then(@NonNull Task<UploadTask.TaskSnapshot> task) throws Exception {
if(!task.isSuccessful()){
throw task.getException();
}
return mStorage.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener<Uri>() {
@Override
public void onComplete(@NonNull Task<Uri> task) {
if(task.isSuccessful()){
String url = task.getResult().toString();
downloadUrl.add(url);
}
}
});
}
Мой массив downloadUrl пуст по запросу URL
Вы можете загрузить свои файлы один за другим и добавить Uri
в список. Поскольку загрузка является асинхронной задачей, вам нужно обернуть весь блок в новый поток и дождаться завершения каждого из них, чтобы они выполнялись один за другим.
Когда я искал, есть существующие сообщения, спрашивающие, как ждать нескольких обратных вызовов. Я разместил ответ в одном из них. Вот ссылка на ответ. Читайте дальше после проверки.
Вот как это выглядит после реализации того, что там описано. (Я не запускал код. Могут быть незначительные ошибки.)
new Thread(new Runnable() {
@Override
public void run() {
final List < String > urls = new ArrayList();
for (int i = 0; i < photos.size(); i++) {
mStorage = FirebaseStorage.getInstance().getReference().child("images/" + j);
mUploadTask = mStorage.putFile(photos.get(i));
final ThreadLockedTask < String > t = new ThreadLockedTask < > ();
final String url = t.execute(new Runnable() {
@Override
public void run() {
Task < Uri > urlTask = uploadTask.continueWithTask(new Continuation < UploadTask.TaskSnapshot, Task < Uri >> () {
@Override
public Task < Uri > then(@NonNull Task < UploadTask.TaskSnapshot > task) throws Exception {
if (!task.isSuccessful()) {
t.setResult(null);
throw task.getException();
}
return mStorage.getDownloadUrl();
}
}).addOnCompleteListener(new OnCompleteListener < Uri > () {
@Override
public void onComplete(@NonNull Task < Uri > task) {
if (task.isSuccessful()) {
String url = task.getResult().toString();
t.setResult(url);
}
}
});
}
});
if(url!=null)
urls.add(url);
}
//Now you have all the urls in the list "urls"
}
}).start();