Обновить область в проекте Android
В настоящее время я использую Realm версии 0.82.0 в одном из моих проектов для Android. Я не трогал Realm довольно долго, пока недавно не заметил, что они поднялись до версии 2.0.2. Я хотел бы обновить свою версию Realm, к сожалению, я не знаю, будет ли обновление моей старой версии до текущей версии работать или сломать мой код.
Я особенно обеспокоен миграциями, так как API для миграций, казалось, немного изменился с момента написания моего кода, и я не уверен, что мои миграции прекратятся, если я просто обновлю свою версию. К сожалению, на их веб-странице нет документации по обновлению версии Realm.
У кого-нибудь есть опыт обновления Realm, особенно увеличение версии по сравнению с двумя основными версиями?
2 ответа
Список критических изменений доступен в CHANGELOG.MD на их Github.
Тем не менее, стоит отметить, что на дороге было довольно много переломных изменений, особенно отметив 0.89.0.
От 0.82.0
в 5.1.0
является следующим (который является наиболее стабильной версией на данный момент):
0.82.0:
BREAKING CHANGE: Поля с аннотацией @PrimaryKey теперь индексируются автоматически. Старые схемы требуют миграции.
(0.82.2 был наиболее стабильным здесь, но он не работал на устройствах Blackberry. Первая стабильная версия для использования на Blackberry была 0.87.2.)
В версии 0.86.0+ вы можете добавить индекс к аннотированному полю, используя
@Override
public void migrate(final DynamicRealm realm, long oldVersion, long newVersion) {
RealmSchema schema = realm.getSchema();
// version check and stuff
RealmObjectSchema personSchema = schema.get("Person");
personSchema.addIndex("fieldName");
0,83:
BREAKING CHANGE: Обновление формата файла базы данных. Файл Realm, созданный этой версией, не может быть использован предыдущими версиями Realm.
BREAKING CHANGE: Удалены устаревшие методы и конструкторы из класса Realm.
BREAKING CHANGE: введены в штучной упаковке типы Boolean, Byte, Short, Integer, Long, Float и Double. Добавлена нулевая поддержка. Введенная аннотация @Required для обозначения поля не обнуляема. String, Date и byte[] стали обнуляемыми по умолчанию, что означает, что RealmMigrationNeededException будет выброшено, если будет открыта предыдущая версия файла Realm.
О, мальчик, это хороший. Поддержка NULL.
Штучные типы для примитивов стали доступны. Типы в штучной упаковке обнуляются по умолчанию. Все String
, Date
, а также byte[]
должен быть аннотирован @Required
, или же schema.setNullable("fieldName", nullability)
и сделать их всех обнуляемыми.
0.84.0:
Добавлены асинхронные запросы. Здесь нет ничего нового с точки зрения схемы.
0.85.0:
BREAKING CHANGE: удалено исключение RealmEncryptionNotSupportedException, поскольку реализация шифрования изменилась в базовом механизме хранения Realm. Шифрование теперь поддерживается на всех устройствах.
BREAKING CHANGE: Realm.executeTransaction () теперь напрямую выбрасывает любое RuntimeException вместо его оборачивания в RealmException (# 1682).
BREAKING CHANGE: RealmQuery.isNull () и RealmQuery.isNotNull() теперь генерируют IllegalArgumentException вместо RealmError, если имя поля является связанным полем, а последний элемент является ссылкой (#1693).
Ничего важного здесь пока нет, хотя:
Установщики в управляемом объекте для RealmObject и RealmList теперь генерируют исключение IllegalArgumentException, если значение содержит недопустимый (неуправляемый, удаленный, закрытый, из другого Realm) объект (#1749).
Этот интересный. Ранее это просто не удалось, так что это к лучшему. Но это тоже самое большое ограничение Царства.
0.86.0:
BREAKING CHANGE: API-интерфейс миграции был заменен новым API.
BREAKING CHANGE: константы RealmResults.SORT_ORDER_ASCENDING и RealmResults.SORT_ORDER_DESCENDING заменены на перечисления Sort.ASCENDING и Sort.DESCENDING.
BREAKING CHANGE: константы RealmQuery.CASE_SENSITIVE и RealmQuery.CASE_INSENSITIVE заменены на перечисления Case.SENSITIVE и Case.INSENSITIVE.
BREAKING CHANGE: Realm.addChangeListener, RealmObject.addChangeListener и RealmResults.addChangeListener содержат сильную ссылку на слушателя, вы должны отменить регистрацию слушателя, чтобы избежать утечек памяти.
BREAKING CHANGE: Удалены устаревшие методы RealmQuery.minimum{Int,Float,Double}, RealmQuery.maximum{Int,Float,Double}, RealmQuery.sum{Int,Float,Double} и RealmQuery.average{Int,Float,Double}. Используйте взамен RealmQuery.min(), RealmQuery.max(), RealmQuery.sum() и RealmQuery.average().
BREAKING CHANGE: Удален RealmConfiguration.getSchemaMediator(), который по ошибке открыт. И RealmConfiguration.getRealmObjectClasses() добавляется в качестве альтернативы для получения набора классов модели (# 1797).
BREAKING CHANGE: Realm.addChangeListener, RealmObject.addChangeListener и RealmResults.addChangeListener генерируют исключение IllegalStateException при вызове в потоке без лупера. Это должно предотвратить регистрацию слушателей, которые не будут вызваны.
Добавлен новый Dynamic API с использованием DynamicRealm и DynamicRealmObject.
Добавлены Realm.getSchema() и DynamicRealm.getSchema().
Новый API-интерфейс миграции, использующий DynamicRealm
вместо Realm.getTable()
,
Некоторые вещи были переименованы, и вы должны отменить регистрацию слушателей изменений, если ваш набор результатов все еще действителен. Но стоит отметить, что вы все равно должны сохранить переменную поля для вашего RealmResults
, потому что Царство Context
имеет только слабую ссылку на это.
0.87.0:
Поддержка RX. Ничего важного.
0.87.2:
Убран явный вызов GC при совершении транзакции (#1925).
Наконец, Realm снова стал стабильным!:)
0.88.0:
Ломать изменения
Realm теперь должен быть установлен как плагин Gradle.
DynamicRealm.executeTransaction () теперь напрямую генерирует любое RuntimeException вместо его оборачивания в RealmException (# 1682).
DynamicRealm.executeTransaction () теперь генерирует исключение IllegalArgumentException вместо молча принятия нулевого объекта Transaction.
Установщики строк теперь генерируют IllegalArgumentException вместо RealmError для недопустимых суррогатов.
DynamicRealm.distinct()/diverAsync() и Realm.distinct()/diverAsync() теперь генерируют исключение IllegalArgumentException вместо UnsupportedOperationException для недопустимого типа или неиндексированного поля.
Все слушатели локальных изменений потока теперь откладываются до следующего события Looper, а не запускаются при фиксации.
Удален RealmConfiguration.getSchemaMediator() из публичного API, который устарел в 0.86.0. Пожалуйста, используйте RealmConfiguration.getRealmObjectClasses(), чтобы получить набор классов модели (# 1797).
Realm.migrateRealm () создает исключение FileNotFoundException, если файл Realm не существует.
Теперь необходимо отписаться от всех наблюдаемых RxJava Царств, чтобы полностью закрыть Царство (# 2357).
Welp. Теперь это AAR. Вы должны добавить к classpath
и запустить его с apply plugin: 'realm-android'
вместо compile ...
зависимость.
Слушатели изменений вызываются только в следующем цикле событий, а не сразу после фиксации. Я... честно говоря, не совсем уверен в последствиях этого, но это означает, что слушатели изменений не работают с фоновыми потоками. Только в петельных потоках (в первую очередь в потоке пользовательского интерфейса).
Улучшения
Поддержка пользовательских методов, пользовательской логики в средствах доступа, имен пользовательских средств доступа, реализации интерфейса и открытых полей в объектах Realm (#909).
Улучшена загрузка.so с помощью ReLinker.
Это совершенно необходимо, поэтому я бы не хотел застрять на 0.87.5 наверняка.
0.89.0:
Ломать изменения
Значение поля @PrimaryKey теперь может быть пустым для типов String, Byte, Short, Integer и Long. Старые области необходимо перенести, используя RealmObjectSchema.setNullable() или добавив аннотацию @Required. (# 2515).
RealmResults.clear () теперь генерирует исключение UnsupportedOperationException. Вместо этого используйте RealmResults.deleteAllFromRealm().
RealmResults.remove (int) теперь генерирует исключение UnsupportedOperationException. Вместо этого используйте RealmResults.deleteFromRealm(int).
RealmResults.sort () и RealmList.sort() теперь возвращают отсортированный результат вместо сортировки на месте.
RealmList.first () и RealmList.last() теперь генерируют ArrayIndexOutOfBoundsException, если RealmList пуст.
Удален устаревший метод Realm.getTable() из общедоступного API.
Realm.refresh () и DynamicRealm.refresh() на Looper больше не имеют никакого эффекта. RealmObject и RealmResults всегда обновляются в следующем цикле событий.
Хорошо, это самый грязный.
1.) вы должны добавить @Required
аннотация для @PrimaryKey
аннотированные поля, потому что null
является допустимым значением первичного ключа.
2.) realm.refresh()
больше не работает. Это будет удалено в любом случае. Вот обходной путь для 1.1.1, хотя, должен использоваться только в фоновых потоках. Впрочем, он снова доступен в Realm 3.2.
3.) getTable()
устранен. Не используйте это. Используйте новый API миграции.
4.) realmResults.sort()
возвращает новый RealmResults, к которому также должен быть добавлен прослушиватель изменений. Я думаю, что это ненадежно, поэтому я бы просто использовать findAllSorted()
вместо.
5.) Вы можете не думать об этом, но
RealmObject и RealmResults всегда обновляются в следующем цикле событий. (ПРИМЕЧАНИЕ: ЭТО НЕ ДАЛЕЕ ИСТИННО, ПОСЛЕ РЕАЛЬНОСТИ 3.1+, ГДЕ ИЗМЕНЯЮТСЯ СЛУЧАИ ИЗМЕНЕНИЯ ВНОВЬ НА
commitTransaction()
)
Это буквально означало, что RealmResults
были обновлены только когда произошел цикл событий, он НЕ был сразу обновлен при вызове realm.commitTransaction()
, Это также означает, что в фоновых потоках RealmResults НЕ обновлялся, когда вы commitTransaction()
Вы должны были запросить их.
RealmResults
как известно, обновляются только после добавления RealmChangeListener
называется. В 1.1.1, когда RealmChangeListener
Все результаты были обновлены.
Это изменение, однако, также изменило поведение итераций в транзакциях. В транзакциях вы всегда видели новейшую версию. Это означало, что запрос был переоценен во время итерации и изменения элементов. (ЭТО ТАКЖЕ ДЕЛО С РЕАЛЬНЫМ 3.0)
Пример, ранее это был действительный код:
RealmResults<Stuff> stuffs = realm.where(Stuff.class).equalTo("something", false).findAll();
while(!stuffs.isEmpty()) {
stuffs.get(0).setSomething(true);
}
// you end up here because stuffs will be empty
// because of live auto-updates in transactions
Тем не менее, это больше не будет работать. Для меня это вызвало проблемы, потому что я иногда повторял, как это
RealmResults<Stuff> stuffs = realm.where(Stuff.class).equalTo("something", false).findAll();
for(int i = 0; i < stuffs.size(); i++) {
stuffs.get(i--).setSomething(true);
}
// I end up here because of live auto-updates
Это проблема, потому что stuffs
больше не будет меняться. Я должен был сделать поиск --
в моем коде и исправить все итерации, как это.
Официальный обходной путь был таким:
RealmResults<Stuff> stuffs = realm.where(Stuff.class).equalTo("something", false).findAll();
for(int i = stuffs.size()-1; i >= 0; i--) {
stuffs.get(i).setSomething(true);
}
// I end up here because of normal iteration
Это все равно будет хорошо работать в 0.89.0.
Начиная с версии 0.89.0, это также допустимый код (а в версии 3.0.0+ автоматически создается коллекция снимков):
RealmResults<Stuff> stuffs = realm.where(Stuff.class).equalTo("something", false).findAll();
for(Stuff stuff : stuffs) {
stuff.setSomething(true);
}
Элементы в результатах все еще становятся недействительными, но сами результаты не меняются. (Это относится и к коллекциям снимков в Realm 3.0.0+).
0.90.0:
Ломать изменения
RealmChangeListener также предоставляет измененный объект / область / коллекцию (#1594).
Все методы JSON в Realm теперь только оборачивают JSONException в RealmException. Все остальные исключения выдаются такими, какие они есть.
Помечены все методы в RealmObject и все открытые классы final (#1594).
Удален BaseRealm из общедоступного API.
Удален HandlerController из общедоступного API.
Удален конструктор RealmAsyncTask из общедоступного API (#1594).
RealmBaseAdapter был перемещен в свой собственный репозиторий GitHub: https://github.com/realm/realm-android-adapters
Формат файла файлов Realm изменен. Файлы будут автоматически обновлены, но открыть файл Realm со старыми версиями Realm невозможно.
Так RealmBaseAdapter
сейчас в realm-android-adapters
, за 1.1.1
царства, использовать 1.3.0
, Также добавляет RealmRecyclerViewAdapter
, За 3.5.0
использовать 2.0.0
или новее.
RealmChangeListeners получил element
параметр. Ура.
Кроме того, дата теперь имеет milisecond
точность.
0.91.0:
Ломать изменения
Удалены все методы @Deprecated.
Вызов Realm.setAutoRefresh() или DynamicRealm.setAutoRefresh() из потока без лупера создает исключение IllegalStateException, даже если autoRefresh имеет значение false (#2820).
Устаревшее множество методов в 0.90.0, поэтому
Главные изменения:
Realm.allObjects * (). Вместо этого используйте Realm.where(clazz).findAll*().
Realm.distinct * (). Вместо этого используйте Realm.where(clazz).distinct*().
DynamicRealm.allObjects * (). Вместо этого используйте DynamicRealm.where(className).findAll*().
DynamicRealm.distinct * (). Вместо этого используйте DynamicRealm.where(className).distinct*().
Realm.allObjectsSorted (поле, сортировка, поле, сортировка, поле, сортировка). Используйте взамен RealmQuery.findAllSorted(field[], sort[])`.
RealmQuery.findAllSorted (поле, сортировка, поле, сортировка, поле, сортировка). Используйте взамен RealmQuery.findAllSorted(field[], sort[])`.
RealmQuery.findAllSortedAsync (поле, сортировка, поле, сортировка, поле, сортировка). Вместо этого используйте RealmQuery.findAllSortedAsync(field[], sort[])`.
RealmConfiguration.setModules (). Вместо этого используйте RealmConfiguration.modules().
Realm.refresh () и DynamicRealm.refresh(). Вместо этого используйте Realm.waitForChange()/stopWaitForChange() или DynamicRealm.waitForChange()/stopWaitForChange().
waitForChange()
на самом деле не работает, так как люди намерены использовать его, так что вот обходной путь для 1.1.1 до 3.1.4, хотя, должен использоваться только в фоновых потоках. refresh()
будет повторно добавлен в 3.2.0.
Также в какой-то момент Realm.getInstance(Context)
был удален, используйте Realm.getInstance(new RealmConfiguration.Builder(Context).build())
вместо.
После этого вышла 1.0.0, так что это в значительной степени именно так.
Кстати, в 1.1.0 insertOrUpdate()
был добавлен, что быстрее, чем copyToRealmOrUpdate()
и не возвращает прокси.
2.0.2:
Первичные ключи являются неизменяемыми для управляемых объектов, после того как они установлены, их нельзя изменить, и при попытке выдается исключение. Также используйте
realm.createObject(clazz, primaryKeyValue)
если вы используетеcreateObject()
создавать объекты.Вы должны позвонить
Realm.init(Context)
в какой-то момент.Конфигуратор больше не получает Контекст.
armeabi
больше не поддерживается. (только v7a и остальные)
Никаких критических изменений до 3.0.0, но куча исправлений.
3.0.0:
RealmResults.distinct () возвращает новый объект RealmResults вместо фильтрации по исходному объекту (# 2947).
RealmResults постоянно обновляется автоматически. Любая транзакция в текущем потоке, которая может повлиять на порядок или элементы RealmResults, немедленно изменит RealmResults, а не изменит его в следующем цикле событий. Стандартный RealmResults.iterator () будет продолжать работать в обычном режиме, что означает, что вы все равно можете удалять или изменять элементы, не влияя на итератор. То же самое не верно для простых циклов for. В некоторых случаях простой цикл for не будет работать ( https://realm.io/docs/java/3.0.0/api/io/realm/OrderedRealmCollection.html), и вы должны использовать новый createSnapshot() метод.
RealmChangeListener для RealmObject теперь также будет запускаться при удалении объекта. Используйте RealmObject.isValid(), чтобы проверить это состояние (#3138). RealmObject.asObservable() теперь будет излучать объект при его удалении. Используйте RealmObject.isValid(), чтобы проверить это состояние (# 3138).
Удалены устаревшие классы Logger и AndroidLogger (#4050).
Благодаря интеграции результатов Realm ObjectStore, RealmResults
снова в транзакциях, как в 0.88.3 и ранее.
Так simple for loops
(индексация с for(int i = 0; ...
) склонен к поломке - это означает, что вам нужно либо выполнить итерацию в обратном порядке, либо сначала создать коллекцию снимков.
OrderedRealmCollection<Thing> snapshot = results.createSnapshot();
for(int i = 0; i < snapshot.size(); i++) { ...
Также, RealmObject
изменение слушателя теперь также будет выдавать при удалении, вам нужно проверить isValid()
в слушателе изменений. Это сделано для того, чтобы вы могли обновить пользовательский интерфейс, если объект был удален в фоновом режиме.
3.1.0:
Обновлен формат файлов Realm. Существующие файлы Realm будут автоматически перенесены в новый формат при их открытии, но более старые версии Realm не могут открыть эти файлы.
Здесь делать нечего, но стоит упомянуть.
3.2.0-3.2.1:
Здесь нечего делать, кроме обновления Proguard, потому что здесь была введена ошибка. Добавлен раздел proguard.
3.3.0: (и 3.3.1)
Ничего не поделаешь, ошибка была исправлена, что вызвало проблему с Proguard в 3.2.0.
3.4.0:
Здесь делать нечего, хотя стоит посмотреть на новое @LinkingObjects
API для обратных отношений.
На самом деле, рекомендуется заменить двунаправленные ссылки однонаправленными ссылками + обратные отношения.
3.5.0:
Ломать перемены
IllegalStateException будет брошено, если данный RealmModule не включает все необходимые классы модели (#3398).
Если вы не указали все объекты RealmObject в modules()
(в случае, если вы используете несколько модулей вместо стандартных, например, RealmObjects из проекта библиотеки), вам необходимо убедиться, что вы фактически предоставляете все RealmObjects, которые являются частью схемы в ваших модулях.
Раньше он молча добавлял их, даже если их не было в модулях, но сейчас это не так.
4.0.0:
Ломать перемены
Внутренний формат файла был обновлен. Открытие более старого Realm обновит файл автоматически, но более старые версии Realm больше не смогут прочитать файл.
[ObjectServer] Обновлена версия протокола до 22, которая совместима только с Realm Object Server> = 2.0.0.
[ObjectServer] Удалены устаревшие API-интерфейсы SyncUser.retrieveUser() и SyncUser.retrieveUserAsync(). Используйте взамен SyncUser.retrieveInfoForUser() и retrieveInfoForUserAsync().
[ObjectServer] SyncUser.Callback теперь принимает универсальный параметр, указывающий тип объекта, возвращаемого при вызове onSuccess.
[ObjectServer] Переименован в SyncUser.getAccessToken в SyncUser.getRefreshToken.
[ObjectServer] Удален устаревший API SyncUser.getManagementRealm().
Вызов Different () для отсортированного RealmResults больше не очищает определенную сортировку (#3503).
Расслабленная верхняя граница параметра типа RealmList, RealmQuery, RealmResults, RealmCollection, OrderedRealmCollection и OrderedRealmCollectionSnapshot.
Realm обновил свою поддержку RxJava1 до RxJava2 (#3497). Realm.asObservable() был переименован в Realm.asFlowable(). RealmList.asObservable() был переименован в RealmList.asFlowable(). RealmResults.asObservable() был переименован в RealmResults.asFlowable(). RealmObject.asObservable() был переименован в RealmObject.asFlowable(). RxObservableFactory теперь возвращает типы RxJava2 вместо типов RxJava1.
Удалены устаревшие API-интерфейсы RealmSchema.close() и RealmObjectSchema.close(). Их больше не нужно называть.
Удален устаревший API RealmResults.removeChangeListeners(). Вместо этого используйте RealmResults.removeAllChangeListeners().
Удален устаревший API RealmObject.removeChangeListeners(). Вместо этого используйте RealmObject.removeAllChangeListeners().
Удалены UNSUPPORTED_TABLE, UNSUPPORTED_MIXED и UNSUPPORTED_DATE из RealmFieldType.
Удален устаревший API RealmResults.distinct()/RealmResults.distinctAsync(). Используйте взамен RealmQuery.distinct()/RealmQuery.distinctAsync().
RealmQuery.createQuery (Realm, Class), RealmQuery.createDynamicQuery (DynamicRealm, String), RealmQuery.createQueryFromResult (RealmResults) и RealmQuery.createQueryFromList(RealmList) были удалены. Используйте взамен Realm.where(Class), DynamicRealm.where(String), RealmResults.where() и RealmList.where().
Таким образом, поддержка Rx1 была заменена поддержкой Rx2, и removeChangeListeners()
был переименован в removeAllChangeListeners()
,
Большинство других вещей влияют только на синхронизируемые области, и с этого момента можно использовать RealmList<String>
, RealmList<Date>
, а также RealmList<Integer>
как часть схемы Realm. Запросы к ним пока не поддерживаются, и они не заполняются create*FromJson
методы.
4.3.1:
Устаревшие
Варианты RealmQuery.findAllSorted() и RealmQuery.findAllSortedAsync() в пользу предиката RealmQuery.sort(). FindAll().
Варианты RealmQuery.distinct () и RealmQuery.distinctAsync() в пользу предиката RealmQuery.distinctValues (). FindAll ()
Вместо того, чтобы использовать realm.where(Blah.class).distinct("something")
или же realm.where(Blah.class).findAllSorted("something")
Теперь вы можете сделать
realm.where(Blah.class)
.distinctValues("something") // subject to change to `distinct()`
.sort("something") // hopefully will change to `sorted()`? // nope, it's `sort`
.findAll();
5.0.0:
Переименован в RealmQuery.distinctValues () в RealmQuery.distinct ()
Удалены ранее устаревшие RealmQuery.findAllSorted(), RealmQuery.findAllSortedAsync() RealmQuery.distinct() и RealmQuery.distinctAsync()`.
Параметр OrderedCollectionChangeSet в OrderedRealmCollectionChangeListener.onChange() больше не может иметь значение null. Используйте взамен changeSet.getState() (#5619).
Так что это означает, что realm.where(...).findAllSorted("field")
должно быть realm.where(...).sort("field").findAll()
,
Также приходит, что OrderedRealmCollectionChangeListener
используется для отправки null
в качестве первоначального набора изменений, теперь это уже не так, и == null
следует заменить на .getState() == OrderedCollectionChangeSet.State.INITIAL
, Это также означает, что вам нужно использовать realm-android-adapters 3.0.0
или новее с Realm 5.0+.
Кроме того, если вы полагались на имена __RealmProxy
классы: они имеют полное имя, включая пакеты, например my_package_SomeObjectRealmProxy
,
ПРАВИЛА ПРОГУРА
#realm older than 0.84.1
-keepnames public class * extends io.realm.RealmObject
-keep @io.realm.annotations.RealmModule class *
-keep class io.realm.** { *; }
-dontwarn javax.**
-dontwarn io.realm.**
#realm 0.84.1+ and older than 1.0.0
-keep class io.realm.annotations.RealmModule
-keep @io.realm.annotations.RealmModule class *
-keep class io.realm.internal.Keep
-keep @io.realm.internal.Keep class *
-dontwarn javax.**
-dontwarn io.realm.**
#realm 0.89.0+ and older than 1.0.0
-keep class io.realm.RealmCollection
-keep class io.realm.OrderedRealmCollection
#realm 3.2.0 and 3.2.1
-keepnames public class * extends io.realm.RealmObject
Основное обновление до Realm от 4+
в 5+
необходимо изменить с:
realm.where(example.class)
.findAllSorted("field")
Для того, чтобы:
realm.where(example.class)
.sort("field")
.findAll();