Возврат после завершения задачи - PullRequest
0 голосов
/ 14 апреля 2020

Я столкнулся с проблемой, и я не знаю, как ее решить.

Я использую пожарную базу Firebase, чтобы найти мне точный Предмет. Это работает. Проблема возникает, когда я хочу, чтобы задача перенастроила этот элемент в пользовательском классе. Поскольку задание firebase firestore является асинхронным, оно возвращает ноль до завершения.

Вот код в классе DataAdapter:

public Data infoFile(int position){

    DocumentReference fileRef = getInfoFile(position); //Method that retrieves the document.

    //Array to set later the Data Object that will retrieve
    final Data[] dataArray = {new Data()};

    fileRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>()
    {
        @Override
        public void onComplete(@NonNull Task<DocumentSnapshot> task)
        {

            if(task.isSuccessful()){
                DocumentSnapshot documentSnapshot = task.getResult();

                if(documentSnapshot.exists()){

                    Data data = documentSnapshot.toObject(Data.class); //Get the data
                    dataArray[0] = data; //Set data
                    System.out.println("before put bundle" + dataArray[0].getName()); //This gets the data
                    //Can't return here.

                }
            }
        }
    }).addOnFailureListener(new OnFailureListener()
    {
        @Override
        public void onFailure(@NonNull Exception e)
        {

        }
    });
    System.out.println("before put bundle and almost return " + dataArray[0].getName());

    //This returns null because task isn't completed yet.  
    return dataArray[0];
}

Я прочитал о создании и взаимодействии, а затем о передаче данных в метод и получить его. Но я не знаю, как это создать / понять. Может быть, я ошибаюсь, и это не работает.

Вопрос: Как я могу вернуть модель данных, когда задача завершена?

Ответы [ 2 ]

0 голосов
/ 14 апреля 2020

Здесь вы не можете вернуть данные, потому что вы не знаете, когда данные будут готовы вернуть их, поэтому вы можете просто изменить метод вызова этой функции:

Теперь я думаю, что вы используете функцию:

Data d =  infoFile(position);
handleData(d);

измените его на:

infoFile(position,new OnCompleteListener<DocumentSnapshot>()
    {
        @Override
        public void onComplete(@NonNull Task<DocumentSnapshot> task)
        {

            if(task.isSuccessful()){
                DocumentSnapshot documentSnapshot = task.getResult();

                if(documentSnapshot.exists()){

                    Data data = documentSnapshot.toObject(Data.class); //Get the data
                    dataArray[0] = data; //Set data
                    System.out.println("before put bundle" + dataArray[0].getName());   

                    //move the handling to here.
                    handleData(data);

                }
            }
        }
    }).addOnFailureListener(new OnFailureListener()
    {
        @Override
        public void onFailure(@NonNull Exception e)
        {

        }
    });

Затем измените функцию на:

public void infoFile(int position,OnCompleteListener<DocumentSnapshot> listener){

    DocumentReference fileRef = getInfoFile(position); //Method that retrieves the document.

    //Array to set later the Data Object that will retrieve
    final Data[] dataArray = {new Data()};

    fileRef.get().addOnCompleteListener(listener);
    System.out.println("before put bundle and almost return " + dataArray[0].getName());

}
0 голосов
/ 14 апреля 2020

Последняя строка вернет ноль, потому что она будет выполнена до завершения onComplete().

onComplete(), с другой стороны, имеет тип возврата void, и вы не можете вернуть значение в этой функции

Вам необходимо создать функцию внутри класса, откуда вы вызываете функцию intoFile

public void setData(Data data){
    //Set value and use
}

И внутри onComplete()

Сделайте это

    @Override
    public void onComplete(@NonNull Task<DocumentSnapshot> task)
    {

        if(task.isSuccessful()){
            DocumentSnapshot documentSnapshot = task.getResult();

            if(documentSnapshot.exists()){

                Data data = documentSnapshot.toObject(Data.class); //Get the data
                dataArray[0] = data; //Set data
                System.out.println("before put bundle" + dataArray[0].getName()); //This gets the data
                setData(data)                }
        }
    }

После того, как значение установлено, вы можете выполнять следующие операции изнутри setData или можете вызвать функция из setData, которая выполняет следующие операции следующим образом.

public void setData(Data data){
    this.data = data;
    executeNextTask(data);
}
...