Короче говоря: я не знаю, почему мой RealmChangeListener не запускается по назначению при определенных обстоятельствах, и я ищу совет, почему RealmChangeListener
не может работать.RealmChangeListener не выполняется при добавлении вскоре после асинхронной записи
Обновление: Я проверял, что RealmResults
остается действительным = true; загружен = ложь. Если я выполнил RealmResults.load()
после добавления слушателя изменений, он выведет неопределенный Throwing Exception 7
в журнале и BadVersionException
, когда я пройду через источник Царства. Я думаю, что это исключение имеет смысл, асинхронная запись обновляет Realm
, и поэтому запрос больше не работает. Однако как основной, так и начальный потоки запускаются как executeTransactionAsync
, которые записываются в MainActivity
, так и асинхронные запросы.
-
У меня есть MainActivity, в котором при нажатии на кнопку асинхронную запись будет выполняться.
У меня есть еще одна кнопка, которая открывает второе действие, которое отображает данные.
Второе действие использует ViewPager с фрагментом для каждой вкладки. Каждая вкладка имеет другой запрос.
Итак, теперь происходит следующее: я открываю второе действие, которое создает четыре фрагмента, не привязывая их к активности.
Затем выполняется запрос, передающий каждому RealmResults
фрагменту, в котором будет установлен RealmChangeListener
для отображения данных после его загрузки. Может ли быть так, что RealmChangeListener
не работает, если фрагмент не привязан к Activity?
Во всяком случае, это метод, во фрагменте, который принимает RealmResults
(созданный findAllAsyncSorted()
) и предполагается, что для обновления данных на адаптере:
public void updateData(OrderedRealmCollection<Bean> realmCollection) {
Timber.v("Delegated data to fragment of adapter %s.", adapter);
this.data = (RealmResults<Bean>) realmCollection;
if (data.isLoaded()) {
Timber.d("Data is already loaded on adapter %s.", adapter);
adapter.updateDataManual(data);
}
if (!data.isValid()) {
Timber.e("Data is not valid.");
}
listener = new RealmChangeListener<RealmResults<Bean>>() {
@Override public void onChange(RealmResults<Bean> newResults) {
Timber.v("Change listener for manual data triggered: %d results in fragment for category %s and adapter %s.",
newResults.size(), category.toString(), adapter);
adapter.updateDataManual(newResults);
}
@Override protected void finalize() throws Throwable {
Timber.d("Finalizing change listener for adapter %s.", adapter);
super.finalize();
}
};
data.addChangeListener(listener);
MyTimer.setRepeatingCallback(() -> {
Timber.v("RealmResults in adapter %s are %s and %s, and the ChangeListener is %s.",
adapter,
data.isValid() ? "valid" : "invalid",
data.isLoaded() ? "loaded" : "not loaded",
listener);
return true;
}, 5000);
}
Как вы можете видеть, я прилагал усилия по обеспечению что запрос действителен и не загружен до тех пор, пока не будет добавлен слушатель изменений и что ни RealmResults
, ни RealmChangeListener
не будут собраны мусором.
Все еще, из четырех RealmChangeListeners
, только два или меньше (иногда ноль) триггера.
Обратите внимание, что это происходит только в том случае, если второе действие открывается вскоре после запуска асинхронной записи в MainActivity. Если я жду 2 секунды, все будет работать по назначению. Я убедился, что RealmChangeListener
не является сборкой мусора, так как после выхода из приложения вызывается finalize()
. Я понятия не имею, что может помешать слушателю работать. Есть ли что-то конкретное, на что я должен обратить внимание?
Ваш объект 'data' выходит из области действия, когда метод заканчивается, поэтому он, скорее всего, является GC'ed. Вам нужно сохранить его в переменной класса. –
@ChristianMelchior это тоже то, что я думал, но у него есть это.data = (RealmResults) realmCollection; 'что означает, что результаты должны быть сохранены как переменная поля уже, но если он меняет их, тогда да –
EpicPandaForce
@ChristianMelchior Действительно я храню его в поле, доступ к которому можно получить только из опубликованного метода. Сейчас я пытаюсь написать тестовый класс, надеюсь, что смогу воспроизвести проблему там. – ferbeb