manejador de finalización de replicación Swift en Android y Java

Arta Son Ucpinar:

Después de años, estoy tratando de desarrollar una aplicación para Android, utilizando Firebase Firestore. básicamente estoy tratando de replicar esta función Swift:

func getCategories(onCompletion completionBlock: @escaping (_ categories: [Category]?, _ error: Error?) -> Void) {

  firestore.collection("cats").getDocuments { (snap, error) in
    guard let snap = snap else {
      completionBlock(nil, error ?? anUnknownError)
      return
    }

    var categories: [Category] = []
    for document in snap.documents {
        let cat = Category.init(data: document.data())
        categories.append(cat)
    }
    completionBlock(categories, nil)
  }
}

Pero no tengo ni idea de lo que es el equivalente de bloques de SWIFT, aunque no saben si existe.

Revisé los códigos fuente base de fuego. Query.get()regresa Task<QuerySnapshot>por lo que trataron de devolver un Task<List<Category>>sin suerte.

¿Alguna ayuda? Gracias.

EDIT: código de Android añadió para aclarar lo que estoy tratando de hacer.

public class FirestoreService {

    private static volatile FirestoreService singleton = new FirestoreService();

    public static FirestoreService getInstance() {
        return singleton;
    }

    private FirebaseFirestore firestore() {
        // default firestore instance
        FirebaseFirestore db = FirebaseFirestore.getInstance();

        // default firestore settings
        FirebaseFirestoreSettings settings = db.getFirestoreSettings();

        // firestore settings builder
        FirebaseFirestoreSettings.Builder builder = new FirebaseFirestoreSettings.Builder(settings);

        // enable timstamps
        builder.setTimestampsInSnapshotsEnabled(true);

        // set new settings to db instance
        db.setFirestoreSettings(builder.build());


        // return db with new settings.
        return db;
    }



    public void getProductCategories(Handler? handler) {

       Task<QuerySnapshot> task = firestore().collection("coll").get();
       task.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
        @Override
        public void onComplete(@NonNull Task<QuerySnapshot> task) {
            try {
                if (task.isSuccessful()) {
                    List<Category> cats = new ArrayList<>();
                    for (QueryDocumentSnapshot doc : task.getResult()) {
                        String id = doc.getId();
                        Map<String, Object> data = doc.getData();
                        Category cat = new Category(id, data);
                        cats.add(cat);
                    }
                    // now I need completion handler
                } else {
                    Log.w("ERROR", "Error getting categories", task.getException());
                }
            } catch (Exception e) {
                Log.e("ERROR", e.getMessage());
            }
        }
    });
    }

}



public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FirestoreService.getInstance().getCategories().addCompletionListener(
            // handle List<Category> and respresent in UI
        );
    }
}
Daniel B.:

usando AsyncTask

Puede utilizar una AsyncTask. Tiene 3 pasos para ello.

1. onPreExecute() - cosas que quiere hacer antes de ejecutar doInBackground(). Esto sucede en el hilo principal interfaz de usuario.

2. doInBackground() - la AsyncTask, va a hacer operaciones en un subproceso en segundo plano (el hilo de fondo es creado por Android por lo que no es necesario preocuparse por ello).

3.onPostExecute() - aquí se puede recibir datos desde el método doInBackground. El método postExecute se ejecuta de nuevo, en el hilo principal interfaz de usuario.

Lo que puede hacer cualquier operación de E / S en doInBackground(), y devolver el valor que ha recibido del servidor o cualquier otra fuente de datos, y onPostExecute(), es el equivalente de un bloque de terminación en veloz.

Cómo declarar

Para su uso AsyncTask, es necesario ampliar el androide AsyncTask.

Por lo que su propia declaración AsyncTask se verá así:

private class MyAsyncTask extends AsyncTask<Void, Void, Void> { ... }

¿Cuáles son los 3 argumentos genéricos que usted pide?

1. Parámetros - el tipo de los parámetros enviados a la tarea después de la ejecución.

2. Progreso - el tipo de las unidades de progreso publicados durante el cómputo de fondo. (Casi siempre lo será Void, a menos que se preocupan por el progreso real de la operación. Tenga en cuenta que esto es Voidcon una letra mayúscula, y no void como el tipo de retorno).

3. Resultado - el tipo del resultado del cálculo de fondo.

Ejemplo completa

private class LongOperation extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... params) {
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Thread.interrupted();
                }
            }
            return "Executed";
        }

        @Override
        protected void onPostExecute(String result) {
            TextView txt = findViewById(R.id.output);
            txt.setText(result); 
        }
    }

En el ejemplo, se crea una falsa, la operación de largo, que no se puede ejecutar en el hilo principal interfaz de usuario (ya que es una operación de bloqueo).

Cuando se termina la operación, devuelve una String, y que mismo String es recibido en el onPostExecute()método (y recuerda, onPostExecute()se ejecuta en el hilo principal interfaz de usuario de nuevo). Por lo que puede cambiar la interfaz de usuario con el valor de cadena que ha recibido de la operación a largo, bloqueando.

Si desea que la documentación, aquí está:

https://developer.android.com/reference/android/os/AsyncTask

El uso de patrón de observador

También puede utilizar el patrón de observador en su situación.

Crear una interfaz, que tiene un método de onSuccess().tener un objeto poner en práctica esa interfaz, y siempre que lo necesite, puede llamar al onSuccess()método.

Ejemplo:

public Interface SuccessInterface{
   void onSuccess()
}

public class SuccessHandler implements SuccessInterface{
   public void onSuccess(){
         //success code goes here
   }

}

a continuación, en su código, tener un SucessHandlerinstanciado, y la llamada onSuccess()cuando es necesario.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=223711&siteId=1
Recomendado
Clasificación