当从Firebase下载图像到我的应用程序时,它似乎运行良好 - 没有例外,当字节流被解码为位图时,我可以在调试器中看到图像 - 位图是来自实例变量的数组。到目前为止一切都很好 - 但是当处理firebase stuf的方法返回并且bitmap-array传递给我的自定义BaseAdapter时 - 位图为null。我想这是由于异步工作 - 这就是Firebase的工作原理 - 对吗?
onCreate-method 中的
FirebaseApp.initializeApp(this);
downloadImage();
MyGridViewAdapter adapter = new MyGridViewAdapter(this, thumbNailBitmap);
所以 - 当downloadImage()返回并且适配器是instanciated时 - 实例变量thumbNailBitmap没有图像,很可能是由于线程问题。
所以我的问题是 - 如何同步工作,以便适配器等到downloadImage()真的完成之后?
我做了一些研究,发现了这个
Tasks.await((..));
但我不知道如何实现这一点。请参阅下面的downloadImage()
private void downloadImage() {
FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference storageRef = storage.getReference();
String[] imageLoc = new String[11];
imageLoc[0] = "cities/autthaya/autthaya1_thumb.jpg";
imageLoc[1] = "cities/autthaya/autthaya2_thumb.jpg";
imageLoc[2] = "cities/bangkok/bangkok1_thumb.jpg";
imageLoc[3] = "cities/bangkok/bangkok2_thumb.jpg";
imageLoc[4] = "nature/nature1_thumb.jpg";
imageLoc[5] = "nature/nature2_thumb.jpg";
imageLoc[6] = "nature/nature3_thumb.jpg";
imageLoc[7] = "gold/gold1_thumb.jpg";
imageLoc[8] = "gold/gold2_thumb.jpg";
imageLoc[9] = "universe/universe1_thumb.jpg";
imageLoc[10] = "universe/universe2_thumb.jpg";
for (int i = 0; i < 11; i++) {
final int index = i;
StorageReference gsReference = storage.getReferenceFromUrl(URL);
StorageReference islandRef = storageRef.child(imageLoc[i]);
final long BUFFER_SIZE = (long) (1024 * 1024 * 2.5F);
islandRef.getBytes(BUFFER_SIZE).addOnSuccessListener(new OnSuccessListener<byte[]>() {
@Override
public void onSuccess(byte[] bytes) {
thumbNailBitmap[index] = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
System.err.println("UNDANTAG: " + exception);
}
});
}
}
我在堆栈中看到了这个线程,但不知道如何使用应用于我的代码的答案。
答案 0 :(得分:0)
不要使用Tasks.await()或任何其他阻止方法阻止主线程。否则,它可能会导致您的应用程序崩溃ANR(应用程序无响应)。
Firebase API是异步的。你肯定会学习异步编程来处理这个问题。 Read more about that here
您可以延迟创建适配器,直到完成异步工作。或者,您可以在工作完成后更新适配器,并在适配器上调用notifyDataSetChanged()之类的方法,以强制它使用新数据进行刷新。