-1

When downloading images from Firebase to my app it seems to work well - no exception and I can see the images in the debugger when the bytestream is decoded to a bitmap - the bitmap is an array from an instance variable. So far so good - but when the method that handles the firebase stuf returns and the bitmap-array is passed to my customized BaseAdapter - the bitmaps are null. I guess this is due to an asyncronous work - this is how Firebase works - right?

in the onCreate-method

  FirebaseApp.initializeApp(this);
  downloadImage();
  MyGridViewAdapter adapter = new MyGridViewAdapter(this, thumbNailBitmap);

So - when downloadImage() returns and the adapter is instanciated - the instance-variable thumbNailBitmap holds no images, most likely due to a threading issue.

So my question is - how to syncronize the work so that the adapter waits until downloadImage() is really done?

I done some reseach and found this

 Tasks.await((..));

But I do not know how to implement this. See the downloadImage() below

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

    }
}

I seen this thread at stack but do not know how to use the answers given applied to my code.

Is it possible to synchronously load data from Firebase?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
java
  • 1,165
  • 1
  • 25
  • 50

1 Answers1

0

Don't block the main thread with Tasks.await() or any other blocking method. Otherwise it may cause your app to crash with an ANR (Application Not Responding).

Firebase APIs are asynchronous. You will definitely learn async programming to deal with this. Read more about that here.

You can delay creating your adapter until the async work is done. Or, you can update the adapter when the work is done and call a method like notifyDataSetChanged() on your adapter to force it to refresh with new data.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441