2017-10-21 4 views
-1

Ich bin auf der Suche nach einer Möglichkeit zum Herunterladen von Dateien aus meinem FirebaseStorage, indem Sie den Pfad an eine statische Funktion übergeben, die Byte-Daten zurückgibt. Ich habe so etwas wie dies versucht, eine Bitmap zu erhalten:Erstellen einer statischen Funktion, die StorageReference-Bytes zurückgibt

public static Bitmap getBitmapFromStringPath(String path) 
{ 
    final Bitmap[] bitmap = new Bitmap[1]; 
    StorageReference storage = FirebaseStorage.getInstance().getReference(path); 
    storage.getBytes(1024 * 1024).addOnSuccessListener(new OnSuccessListener<byte[]>() { 
     @Override 
     public void onSuccess(byte[] bytes) { 
      bitmap[0] = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); 
     } 
    }); 
    return bitmap[0]; 
} 

Natürlich ist dies nicht funktioniert wie erwartet (alle Erträge sind null), da Firebase ein Echtzeit-Dienst ist, aber ich bin sicher, es gibt einige Workarounds erreiche was ich suche. Ich brauche etwas Einfaches und Einfaches.

Antwort

0

Dies wird nicht so sehr durch Firebases Echtzeitverhalten verursacht, sondern eher dadurch, dass das Herunterladen einer Datei eine asynchrone Aktivität ist. Wenn dies nicht der Fall wäre, würde das Aufrufen von getBitmapFromStringPath den Benutzer daran hindern, mit Ihrer App zu interagieren, und Android würde den Dialog "Anwendung reagiert nicht" anzeigen.

Die Lösung hier ist:

  • entweder den Code bewegen, die die Bytes ingetBitmapFromStringPath
  • oder geben Sie das Task unsere von getBitmapFromStringPath muss.

Der einfachste Weg, mit asynchronem Verhalten umzugehen ist, um den Code zu verschieben, die die Bytes in den Erfolg Hörer braucht:

public static void getBitmapFromStringPath(String path) 
{ 
    final Bitmap[] bitmap = new Bitmap[1]; 
    StorageReference storage = FirebaseStorage.getInstance().getReference(path); 
    storage.getBytes(1024 * 1024).addOnSuccessListener(new OnSuccessListener<byte[]>() { 
     @Override 
     public void onSuccess(byte[] bytes) { 
      bitmap[0] = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); 
      // TODO: Do what you need with bitmap 
     } 
    }); 
} 

Dies könnte erfordern, dass Sie zusätzliche Informationen weitergeben, wie die anzeigen, dass Sie die Bitmap in festlegen möchten.

Alternative, betrachtet die Aufgabe zurückzukehren und hat dann den Erfolg Zuhörer in dem Code, die getBitmapFromStringPath ruft:

public static Task<byte[]> getBitmapFromStringPath(String path) 
{ 
    final Bitmap[] bitmap = new Bitmap[1]; 
    StorageReference storage = FirebaseStorage.getInstance().getReference(path); 
    return storage.getBytes(1024 * 1024) 
} 

Und dann:

getBitmapFromStringPath("...").addOnSuccessListener(new OnSuccessListener<byte[]>() { 
    @Override 
    public void onSuccess(byte[] bytes) { 
     bitmap[0] = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); 
     // TODO: Do what you need with bitmap 
    } 
}); 
+0

ich mich verändert habe, dass das Image stattdessen zu aktualisieren und sieht gut aus. Ich habe auch versucht, Tasks.await() zu tun, aber es ist fehlgeschlagen. Es macht mir nichts aus, den UI-Thread überhaupt zu blockieren. Was können Sie dazu vorschlagen? –

+0

Sie können den UI-Thread nicht blockieren, aber Ihre Benutzer werden es tun. Deshalb erkennt Android dies und zeigt den Dialog "Anwendung reagiert nicht". Eine separate Antwort hierzu (unter Verwendung der Echtzeitdatenbank, aber auch für Cloud Storage) finden Sie unter: https://stackoverflow.com/questions/33203379/setting-singleton-property-value-in-firebase-listener –

+0

I Ich habe versucht, viele von denen warten, semaphore und Countdown ohne Glück. Ich habe es geschafft, die Daten mit einem HTTP-GET-Aufruf zu bekommen, aber das wird mir nicht helfen mit dem im Gerät zwischengespeicherten Firebase-Daten :( Ich werde aufgeben .... aber es sollte in Zukunft Art von synchronen Operationen sein .. danke für Ihre Hilfe Frank –

Verwandte Themen