FIrebase - 使用mainthread同步下载

时间:2018-04-20 16:38:17

标签: android multithreading firebase asynchronous firebase-realtime-database

当从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);
            }
        });

    }
}

我在堆栈中看到了这个线程,但不知道如何使用应用于我的代码的答案。

Is it possible to synchronously load data from Firebase?

1 个答案:

答案 0 :(得分:0)

不要使用Tasks.await()或任何其他阻止方法阻止主线程。否则,它可能会导致您的应用程序崩溃ANR(应用程序无响应)。

Firebase API是异步的。你肯定会学习异步编程来处理这个问题。 Read more about that here

您可以延迟创建适配器,直到完成异步工作。或者,您可以在工作完成后更新适配器,并在适配器上调用notifyDataSetChanged()之类的方法,以强制它使用新数据进行刷新。