Метод "LiveData" getAll "возвращает 0, когда приложение устанавливается в первый раз. - PullRequest
0 голосов
/ 02 августа 2020

Я использую Room, в моем dao у меня есть метод:

@Query("SELECT * FROM Flower")
LiveData<List<Flower>> getAllFlowers();

В своей деятельности я вызываю этот метод через ViewModel:

flowerViewModel.getAllFlowers().observe(ExampleFlowerbedActivity.this, new Observer<List<Flower>>() {
                    @Override
                    public void onChanged(List<Flower> flowers) {
                         ...
                         int current_color = getRandom(flowers);
                         ...
                    }
                });

Inside I ' m вызывает метод getRandom ():

public Integer getRandom(List<Flower> flowers){
                        Flower random = randomFlower(flowers); // here I get an error
                        addedToLayoutFlowers.add(random);
                        List<Integer> random_color = random.getColors_ids();
                        return randomColor(random_color);
                    }

Метод randomFlower выглядит так:

public Flower randomFlower(List<Flower> list){
    rand = new Random();
    return list.get(rand.nextInt(list.size()));
}

И я получаю эту ошибку:

java.lang.IllegalArgumentException: n <= 0: 0

Я проверил Значение списка, которое я получаю из базы данных, и оно равно 0, только когда я устанавливаю приложение и посещаю это действие в первый раз. Когда я закрываю ошибку и снова открываю приложение, все работает идеально. В чем может быть проблема? Спасибо за любую помощь.

Изменить: Я добавляю цветы прямо в класс базы данных:

@Database(entities = {Flower.class}, version = 2)
@TypeConverters(TypeConverter.class)
public abstract class FlowerDatabase extends RoomDatabase {

private static FlowerDatabase instance2;

public abstract FlowerDao flowerDao();

public static synchronized FlowerDatabase getInstance1(Context context) {
    if (instance2 == null) {
        instance2 = Room.databaseBuilder(context.getApplicationContext(),
                FlowerDatabase.class, "flower_database")
                .fallbackToDestructiveMigration()
                .addCallback(room1Callback)
                .build();
    }
    return instance2;
}

private static RoomDatabase.Callback room1Callback = new RoomDatabase.Callback(){
    @Override
    public void onCreate(@NonNull SupportSQLiteDatabase db) {
        super.onCreate(db);
        new Populate1DBAsyncTask(instance2).execute();
    }
};

private static class Populate1DBAsyncTask extends AsyncTask<Void, Void, Void> {

    private FlowerDao flowerDao;

    private Populate1DBAsyncTask(FlowerDatabase db){
        flowerDao = db.flowerDao();
    }

    @Override
    protected Void doInBackground(Void... voids) {

    flowerDao.insertFlower(new Flower(....)); // HERE

    ));
        return null;
    }
    }
    } 

1 Ответ

1 голос
/ 03 августа 2020

Судя по опубликованному вами коду, у вас есть состояние гонки. Room не создает базу данных до первого запроса на выполнение операции в базе данных. Полагаю, это ваш звонок по номеру getAllFlowers(). Только после этого вызова будет создана база данных и выполнен обратный вызов onCreate(). Поскольку заполнение базы данных запускается onCreate() и выполняется как фоновая задача, она не завершается до запуска кода вашего основного потока. getAllFlowers() возвращает пустой список цветов, что вызывает исключение.

Вам необходимо переделать свой код, чтобы гарантировать, что добавление цветов завершено до запроса базы данных. Или рассмотрите возможность использования предварительно заполненной базы данных .

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