Размер списка по какой-то причине возвращается к нулю - PullRequest
0 голосов
/ 17 января 2020

Я загружаю данные из облака firestore в специальный адаптер для повторного использования. Согласно моему журналу, я получаю данные из firestore очень хорошо, и внутри моего метода get журнал показывает увеличение моего списка. Вне моего метода get mWorkoutList возвращается к размеру 0. Я не могу понять, почему это происходит. Log shows mWorkoutList size going back to 0

public class ViewWorkoutsActivity extends AppCompatActivity implements WorkoutAdapter.WorkoutAdapterOnClickHandler {

private final String TAG = this.getClass().getName();
private FirebaseFirestore db;
private String mUid;
private List<Set> mSetList;
private RecyclerView mRecyclerView;
private WorkoutAdapter mWorkoutAdapter;
private List<OtherWorkout> mWorkoutList;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_view_workouts);
    mWorkoutList = new ArrayList<>();
    mUid = getIntent().getStringExtra("uid");
    db = FirebaseFirestore.getInstance();
    initDatabaseData();

    mRecyclerView = findViewById(R.id.recycler_view);

    LinearLayoutManager linearLayoutManager
            = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
    mRecyclerView.setLayoutManager(linearLayoutManager);
    mRecyclerView.setHasFixedSize(true);
    mWorkoutAdapter = new WorkoutAdapter(this);
    mRecyclerView.setAdapter(mWorkoutAdapter);
    Log.i("LOG", "workout list size HERE: " + mWorkoutList.size());
    mWorkoutAdapter.setWorkoutData(mWorkoutList);
}

@Override
public void onClick(OtherWorkout workout) {

}

public void initDatabaseData(){
    CollectionReference collectionReference2 = db.collection("users").document(mUid).collection("workouts");
    collectionReference2.get()
            .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) {
                    if(task.isSuccessful()){
                        for (QueryDocumentSnapshot document : task.getResult()){
                            OtherWorkout workout = document.toObject(OtherWorkout.class);
                            mWorkoutList.add(workout);
                            Log.i("LOG", "workout list size: " + mWorkoutList.size());
                        }
                    }
                }
            });
}
}

Ответы [ 4 ]

2 голосов
/ 17 января 2020

Привет Аллен, ты вызываешь initDatabaseData (); в методе oncreate (), который выполняет сетевой запрос и получает данные. Таким образом, получение данных занимает примерно 2-3 секунды. Но через 2-3 секунды ваш код ниже initDatabaseData () будет вызван

 LinearLayoutManager linearLayoutManager
        = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(linearLayoutManager);
mRecyclerView.setHasFixedSize(true);
mWorkoutAdapter = new WorkoutAdapter(this);
mRecyclerView.setAdapter(mWorkoutAdapter);
Log.i("LOG", "workout list size HERE: " + mWorkoutList.size());
mWorkoutAdapter.setWorkoutData(mWorkoutList);

Так что до тех пор, пока данные не поступят, размер списка будет отображаться 0, а затем после того, как вы получите данные в списке onComplete (), размер будет увеличение(). Поэтому в основном добавьте строку mWorkoutAdapter.notifyDatasetChanged (); здесь: -

if(task.isSuccessful()){
                    for (QueryDocumentSnapshot document : task.getResult()){
                        OtherWorkout workout = document.toObject(OtherWorkout.class);
                        mWorkoutList.add(workout);
                        Log.i("LOG", "workout list size: " + mWorkoutList.size());
                    }mWorkoutAdapter.notifyDatasetChanged();

                }

Это обновит sh ваш адаптер с вашими новыми значениями.

0 голосов
/ 17 января 2020

addOnCompleteListener предоставляет способ добавить асинхронный прослушиватель задач.

Когда вы вызываете initDatabaseData(), вы запускаете задачу и определяете прослушиватель. Но нет никакой гарантии, что эта задача будет выполнена при возврате из initDatabaseData.

. Поэтому, когда вы печатаете размер mWorkoutList в методе onCreate, значение может отличаться от значения, напечатанного в слушатель.

Чтобы избежать этого, вы можете изменить способ работы вашей программы, либо изменив механизм asyn c на механизм syn c, либо с помощью части, использующей данные для слушателя onComplete метод

0 голосов
/ 17 января 2020

Вы можете проверить свои

  Log.i("LOG", "workout list size: " + mWorkoutList.size());

после

 Log.i("LOG", "workout list size HERE: " + mWorkoutList.size());

, так что это означает, что firebase займет некоторое время для извлечения всех данных, за это время исполняется ваш оставшийся код. , поэтому решение вызывается initDatabaseData () после установки адаптера, а затем вызывается adapter.notifydatasetchanged (). или вы можете напрямую уведомить адаптер в методе initDatabaseData () после извлечения данных.

0 голосов
/ 17 января 2020

Вы создаете OtherWorkout как локальный объект, а затем добавляете его в коллекцию. Если ваша get() функция выходит за рамки видимости, объект будет автоматически удален.

Я не проверял, но я думаю, что сборщик мусора Java позаботится обо всем остальном и удалит объект из массива.

Вы должны создать объекты в куче с помощью new, чтобы они сохранялись вне области действия этой функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...