Java中使用StorageReference从Firebase Storage获取文件夹名到ArrayList为空的问题求助
问题原因
你的问题核心是Firebase Storage的listAll()是异步操作:代码调用listAll()后会立即继续执行后续逻辑,而onSuccess回调要等网络请求完成后才会触发。所以当你在Activity生命周期后期去访问articles时,回调还没执行,集合自然为空。
解决方案
下面提供两种可行的处理方式,你可以根据需求选择:
方式一:在回调内直接处理数据(最常用)
既然回调是数据准备完成的唯一时机,所有需要使用articles的逻辑(比如更新UI、打印数据)都应该放在onSuccess回调内部:
public class NewActivity extends AppCompatActivity { List<Article> articles = new ArrayList<>(); // 补充分号 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_themes); // 通常不需要手动初始化FirebaseApp,Firebase会自动完成 FirebaseStorage storage = FirebaseStorage.getInstance(); StorageReference reference = storage.getReference("themes"); reference.listAll().addOnSuccessListener(new OnSuccessListener<ListResult>() { @Override public void onSuccess(ListResult listResult) { for (StorageReference prefix : listResult.getPrefixes()) { articles.add(new Article(prefix.getName())); } // 在这里处理加载完成后的逻辑,比如更新UI updateUIWithArticles(); // 或者直接使用articles集合 Log.d("Storage", "加载到的文件夹数量:" + articles.size()); } }).addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { e.printStackTrace(); // 处理加载失败的情况 } }); } // 示例:更新UI的方法 private void updateUIWithArticles() { // 比如给RecyclerView设置适配器等操作 } }
方式二:使用Tasks.whenAll()等待任务完成
如果你需要在回调外统一处理多个异步任务(这里虽然是单个任务,但可以演示用法),可以用Tasks.whenAll()包裹listAll()任务,然后添加完成监听:
public class NewActivity extends AppCompatActivity { List<Article> articles = new ArrayList<>(); protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_themes); FirebaseStorage storage = FirebaseStorage.getInstance(); StorageReference reference = storage.getReference("themes"); // 获取listAll的Task对象 Task<ListResult> listTask = reference.listAll(); // 使用Tasks.whenAll等待任务完成 Tasks.whenAll(listTask).addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { if (task.isSuccessful()) { ListResult listResult = listTask.getResult(); for (StorageReference prefix : listResult.getPrefixes()) { articles.add(new Article(prefix.getName())); } // 数据加载完成,在这里处理逻辑 Log.d("Storage", "Tasks加载完成,文件夹数量:" + articles.size()); } else { // 处理失败 task.getException().printStackTrace(); } } }); } }
注意事项
- 不要在主线程中调用
task.getResult()阻塞等待,这会导致ANR(应用无响应),必须通过回调处理结果。 - 如果需要在Activity销毁后继续执行任务,要考虑使用ViewModel或LifecycleOwner来避免内存泄漏。
内容的提问来源于stack exchange,提问作者vad070
相关产品推荐
相关产品推荐

