Обновление области в Android-проекте

В настоящее время я запускаю Realm Version 0.82.0 в одном из моих Android-проектов. Некоторое время я не касался Королевства, пока я не заметил, что они поднялись до версии 2.0.2. Я хотел бы обновить свою версию Realm, к сожалению, я не знаю, будет ли обновление от моей старой версии до текущей версии работать или нарушать мой код.

Я особенно обеспокоен миграциями, поскольку API для миграции, похоже, немного изменился с моего кода, и я не уверен, что мои миграции будут разорваны, если я просто обновлю свою версию. К сожалению, нет документации по обновлению версии Realm, доступной на их веб-странице.

Есть ли у кого-нибудь опыт обновления Realm, особенно если версия больше двух основных версий?

Список изменений с изменением доступен в 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: Удалены устаревшие методы и конструкторы из classа Realm.

BREAKING CHANGE: Введенные типы в буфере, Boolean, Byte, Short, Integer, Long, Float и Double. Добавлена ​​нулевая поддержка. Введенная аннотация @ Требуется указать, что поле не равно NULL. 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 () добавляется в качестве альтернативы для получения набора classов моделей (# 1797).

BREAKING CHANGE: Realm.addChangeListener, RealmObject.addChangeListener и RealmResults.addChangeListener будет вызывать исключение IllegalStateException при вызове в streamе, отличном от Looper. Это делается для предотвращения регистрации слушателей, которые не будут вызываться.

Добавлен новый Dynamic API с использованием DynamicRealm и DynamicRealmObject.

Добавлены Realm.getSchema () и DynamicRealm.getSchema ().

Новый API миграции, используя DynamicRealm вместо Realm.getTable() .

Некоторые вещи были переименованы, и вы должны отменить регистрацию своих слушателей изменений, если ваш результирующий набор все еще действителен. Но стоит отметить, что вы должны сохранить переменную поля для своих RealmResults , потому что Context Realm’s имеет только слабую ссылку на него.

0,87,0 :

Поддержка RX. Ничего важного.

0,87,2 :

Удаленный явный вызов GC при совершении транзакции (# 1925).

Наконец, Realm снова стал стабильным! 🙂

0,88,0 :

Нарушение изменений

Теперь Realm должен быть установлен как плагин Gradle.

DynamicRealm.executeTransaction () теперь напрямую выдает любое RuntimeException вместо того, чтобы обернуть его в RealmException (# 1682).

DynamicRealm.executeTransaction () теперь выдает исключение IllegalArgumentException вместо молчащего принятия объекта null Transaction.

Строковые сеттеры теперь вытесняют IllegalArgumentException вместо RealmError для недействительных суррогатов.

DynamicRealm.distinct () / distinctAsync () и Realm.distinct () / distinctAsync () теперь вызывают исключение IllegalArgumentException вместо UnsupportedOperationException для недопустимого типа или неиндексированного поля.

Все пользователи локального изменения streamа теперь задерживаются до следующего события Looper, а не запускаются при совершении.

Удалено RealmConfiguration.getSchemaMediator () из общедоступного API, который устарел в 0.86.0. Используйте RealmConfiguration.getRealmObjectClasses (), чтобы получить набор classов моделей (# 1797).

Realm.migrateRealm () выдает исключение FileNotFoundException, если файл Realm не существует.

Теперь необходимо отказаться от всех наблюдаемых данных Realm RxJava, чтобы полностью закрыть Царство (# 2357).

Welp. Сейчас это AAR. Вы должны добавить в classpath и запустить его с помощью apply plugin: 'realm-android' вместо compile ... зависимости.

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

Улучшения

Поддержка пользовательских методов, настраиваемая логика в аксессуарах, пользовательские имена аксессуаров, реализация интерфейса и общедоступные поля в объектах Realm (# 909).

Улучшена загрузка .so с помощью ReLinker.

Это очень необходимо, хотя я бы не захотел застрять на 0.87.5.

0.89.0:

Нарушение изменений

Значение поля @PrimaryKey теперь может быть нулевым для типов String, Byte, Short, Integer и Long. Старые царства должны быть перенесены с использованием RealmObjectSchema.setNullable () или путем добавления annotations @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, хотя он должен использоваться только для фоновых streamов. Тем не менее, он доступен в Realm 3.2.

3.) getTable() удаляется. Не используйте его. Используйте новый API миграции.

4.) realmResults.sort() возвращает новые RealmResults, в которых также должен быть добавлен слушатель изменений. Я думаю, что это ненадежно, поэтому я бы просто использовал findAllSorted() .

5.) Вы можете не думать об этом много, но

RealmObject и RealmResults всегда обновляются в следующем цикле событий. ( ПРИМЕЧАНИЕ: ЭТО НЕ ДОЛЖНО ИСТИННО С ПОМОЩЬЮ REALM 3.1+ ГДЕ ИЗМЕНИТЬ СЛУЖБЫ СЛУЖБЫ СНОВА НА commitTransaction() )

Это буквально означало, что RealmResults были обновлены только тогда, когда произошел цикл события, он НЕ был немедленно обновлен, когда вы вызываете realm.commitTransaction() . Это также означает, что в фоновом streamе RealmResults не обновлялись, когда вы commitTransaction() , вы должны требовать их.

Известно, что RealmResults обновляется после RealmChangeListener добавленного RealmChangeListener . В 1.1.1, когда RealmChangeListener , все результаты были обновлены.

Однако это изменение также изменило итерационное поведение в транзакциях. В транзакциях вы всегда видели самую новую версию. Это означало, что запрос был повторно оценен по мере повторения на нем и изменения элементов. ( ЭТО ТАКЖЕ СЛУЧАЙ ПОСЛЕ REALM 3.0 )

Например, ранее это был действительный код:

 RealmResults 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 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 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 stuffs = realm.where(Stuff.class).equalTo("something", false).findAll(); for(Stuff stuff : stuffs) { stuff.setSomething(true); } 

Элементы результатов все равно становятся недействительными, но сами результаты не меняются. (Это то же самое для коллекций снимков, а также в Realm 3.0.0+).

0.90.0:

Нарушение изменений

RealmChangeListener также предоставляет измененный объект / Realm / collection (# 1594).

Все методы JSON в Realm теперь только перекрывают исключение JSONException в RealmException. Все остальные Исключения выбрасываются как есть.

Отмечены все методы в RealmObject и все общедоступные classы final (# 1594).

Удалено BaseRealm из общедоступного API.

Удалено HandlerController из общедоступного API.

Удаленный конструктор RealmAsyncTask из общедоступного API (# 1594).

RealmBaseAdapter был перемещен в собственный repository GitHub: https://github.com/realm/realm-android-adapters

Изменен формат файла Realm. Файлы будут автоматически обновляться, но открытие файла Realm со старыми версиями Realm невозможно.

Итак, RealmBaseAdapter теперь находится в realm-android-adapters , для 1.1.1 of Realm, используйте 1.3.0 . Также добавляется RealmRecyclerViewAdapter . Для 3.5.0 используйте 2.0.0 или новее.

RealmChangeListeners получил параметр element . Ура.

Кроме того, дата теперь имеет milisecond точность.

0.91.0:

Нарушение изменений

Удалены все методы @Deprecated.

Вызов Realm.setAutoRefresh () или DynamicRealm.setAutoRefresh () из streamа non-Looper вызывает IllegalStateException, даже если autoRefresh является ложным (# 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 (поле [], sort []) `.

RealmQuery.findAllSorted (поле, сортировка, поле, сортировка, поле, сортировка). Вместо этого используйте RealmQuery.findAllSorted (поле [], sort []) `.

RealmQuery.findAllSortedAsync (поле, сортировка, поле, сортировка, поле, сортировка). Вместо этого используйте RealmQuery.findAllSortedAsync (поле [], sort []) `.

RealmConfiguration.setModules (). Вместо этого используйте RealmConfiguration.modules ().

Realm.refresh () и DynamicRealm.refresh (). Вместо этого используйте Realm.waitForChange () / stopWaitForChange () или DynamicRealm.waitForChange () / stopWaitForChange ().

waitForChange() самом деле не работает, поскольку люди намерены его использовать, поэтому обходной путь для 1.1.1 - 3.1.4, однако, должен использоваться только для фоновых streamов. refresh() будет добавлен в 3.2.0.

Кроме того, в какой-то момент Realm.getInstance(Context) был удален, Realm.getInstance(new RealmConfiguration.Builder(Context).build()) используйте 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) в какой-то момент.

  • Configuration Builder больше не получает контекст.

  • armeabi больше не поддерживается. (только v7a и другие)


Никаких изменений до 3.0.0, кроме тонны исправлений.


3.0.0:

RealmResults.distinct () возвращает новый объект RealmResults вместо фильтрации на исходном объекте (# 2947).

RealmResults автоматически обновляется автоматически. Любая транзакция текущего streamа, которая может повлиять на порядок или элементы RealmResults, немедленно изменит RealmResults вместо изменения в следующем цикле событий. Стандартный RealmResults.iterator () будет продолжать работать как обычно, а это значит, что вы все равно можете удалять или изменять элементы без воздействия на iterator. То же самое не верно для простых for-loops. В некоторых случаях простой for-loop не будет работать ( https://realm.io/docs/java/3.0.0/api/io/realm/OrderedRealmCollection.html#loops ), и вы должны использовать новый createSnapshot () метод.

RealmChangeListener в RealmObject теперь также будет запущен, когда объект будет удален. Используйте RealmObject.isValid (), чтобы проверить это состояние (# 3138). RealmObject.asObservable () теперь выдает объект при его удалении. Используйте RealmObject.isValid (), чтобы проверить это состояние (# 3138).

Удалены устаревшие classы Logger и AndroidLogger (# 4050).

Благодаря интеграции результатов RealmResults снова работает в транзакциях, как и в 0.88.3 и ранее.

Так simple for loops (индексирование с for(int i = 0; ... ) подвержено разрыву - это означает, что вам нужно либо перевернуть их, либо создать коллекцию снимков.

 OrderedRealmCollection snapshot = results.createSnapshot(); for(int i = 0; i < snapshot.size(); i++) { ... 

Кроме того, RealmObject change listener теперь также будет 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:

Здесь нечего делать, хотя стоит посмотреть на новый API @LinkingObjects для обратных отношений.

На самом деле, рекомендуется заменять двунаправленные ссылки на однонаправленную связь + обратную связь.

3.5.0:

Нарушение изменений

Исключение IllegalStateException будет выведено, если данный RealmModule не включает все требуемые classы моделей (# 3398).

Если вы не указали все объекты RealmObjects в modules() (если вы используете несколько модhive, а не только по умолчанию, например RealmObjects из проекта библиотеки), то вам нужно убедиться, что вы действительно предоставляете все объекты RealmObject, которые являются частью схема в ваших модулях.

Раньше он молча добавлял их, даже если они не были в модулях, теперь это не так.

4.0.0:

Нарушение изменений

Обновлен внутренний формат файла. Открытие более старого Realm автоматически обновит файл, но более старые версии Realm больше не смогут читать файл.

[ObjectServer] Обновлена ​​версия протокола до 22, которая совместима только с сервером объектов Realm> = 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 ().

Вызов distinct () на отсортированных 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() .

Большинство других вещей влияют только на Reals, и с этой точки можно использовать RealmList , RealmList и RealmList как часть схемы 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 () больше недействителен. Вместо этого используйте 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+.

Кроме того, если вы полагаетесь на имена classов __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 
  • Как убить приложение со всеми его действиями?
  • Связь между деятельностью и службой
  • Как можно обнаружить режим самолета на Android?
  • Пользовательский агент Android HTTP
  • Позиционирование MediaController над VideoView
  • Как реализовать перетаскиваемую карту, например, uber android, Update with change location
  • Android: Есть ли способ изменить язык по умолчанию для Android на новый язык?
  • Как получить Bitmap от Uri?
  • Поместите неопределенный прогресс в качестве нижнего колонтитула в сетке RecyclerView
  • Как правильно выделить выделенный элемент в RecyclerView?
  • Вращение изображения на canvasе в андроиде
  • Давайте будем гением компьютера.