Pull to refresh

Comments 19

Здравствуйте. Спасибо за статью.

Лично считаю, что на Андроиде подобные вещи — от лукавого, курсор по эффективности ничего не обгонит. У меня есть несколько вопросов и комментариев. Начну с комментариев.

Первый комментарий по-поводу метода onTerminate в Вашем Application. Проблема с этим методом, что он не вызывается на реальных устройствах, и это явно прописано в документации. Ваше соединение будет жить все время, пока живо приложение, т. е., пока процесс жив, и висит в кэше.

Второй комментарий имена методов SetHelper, GetHelper — это страшно!

Вопросы:

1. Если у Вас имеется список в 1000 элементов (допустим, фид какой-нибудь), будут ли все эти 1000 элементов загружены в память из базы данных для отображения при запросе? Как это дело уживается с AdapterView? Не говорите мне, что используете ArrayAdapter
2. Насколько это дружит с ContentProvider?
3. Как у этого дела с транзакциями, особенно, при вставке в БД 1000 записей?
Согласен с вами, ContentProviderы и курсоры, на мой взгляд, гораздо эффективнее и удобнее в системе.

Насколько я понял из описания, с ContentProviderом это подружить не получится, здесь ведь сразу возвращаются объекты модели, не курсор.
Похоже в связке с ORM необходимо использовать ArrayAdapter. Проблемы с 1000 записей может решить разве что динамическая подгрузка
Необходимость использовать ArrayAdapte при списке в 1000 записей, ИМХО, сигнал, что в этом подходе есть большие проблемы.
не обязательно ведь грузить в память все 1000 записей из таблицы, можно подгружать по мере прокрутки, как это часто делается
Ага, только курсор дает вам это бесплатно, а тут придется повозиться. И «удобство» подобного фреймворка сразу подуменьшися.
ну собственно, я это и утверждал, что с ORM фреймворком вместо курсора придется ArrayAdapter использовать, что неудобно.

не до конца еще прояснил для себя момент: разве все данные запроса не грузятся в курсор сразу? CursorAdapter вроде только вытягивает данные из готового курсора для отображения.
Нет. Стандартный курсор внутри устроен достаточно сложно и держит определенное окошко, которое по мере итерации обновляет. Поэтому у вас может быть много много данных, но за счет окна в курсоре и реюза вьюх в ListView, с отображением этого больших проблем не возникнет.
то есть по мере итерации курсора или при скролле он регулярно делает запросы к бд?
надо будет посмотреть исходники курсора
При первом запросе создается SQL statement, а дальше при заполнении окна вызывается sqlite3_step.
Как видите, эта схема поддерживается на уровне самого sqlite. Никаких доп. запросов он не делает.
И мои пять копеек к orm for android: ActiveAndroid (Active record style SQLite persistence for Android). Это уже конечно более высокий уровень по сравнению с курсором, и подгрузка данных происходит тогда когда она нужна, НО в андроиде этот подход опять же не оправдан, т.к. здесь везде хотят курсор, и кто его знает как эти все ORM монстры «запоют» на каком-нибудь huawei ideos :). В отличии от Android, в iOS ActiveRecord подход оправдан, там хотя бы железо всегда адекватное.
Говоря проще, cursor — это пошаговое отложенное выполнение запроса, вот :)
ArrayAdapter вполне использовать и для 10к записей. Например если есть возможность подождать, а данные не хочется никуда пихать далеко (в бд там или еще куда), то можно просто совместить, скажем, загрузку с сервера и загрузку данных из локального хранилища для наполнения адаптера. Вполне нормальный подход для грамотно написанного приложения, которое нигде не течет, забивая весь хип.
Ну, статья-то как раз о работе с БД. Поэтому и вопрос об ArrayAdapter шел именно в этом контексте. Не имеет смысла в целом расписывать преимущества AA и юзкейсы, когда он действительно нужен. В Андроид нету ненужных компонентов, просто каждому свое применение.
В целом статья неплоха, но есть огрехи. В дополнение к предыдущему комментатору хочу заметить, что синглтоны у вас не thread-safe, что слегка печалит.
Спасибо, полезная статья и очень вовремя.
Для небольших проектов ORM может вполне так упростить (ускориить) разработку и это плюс. На деле же полгода назад я пробовал юзать ORMlite (пробовал даже DB4o), но в итоге, после фикса каких-то глубинных багов и разборе исходников оказалось, что ORMlite сложно заставить понимать циклические связи.

В целом впечатление положительное. Честь и хвала ребятам.
В итоге что используете?
Свои DAO-обертки и синглтон хелпер к базе. На днях буду пробовать снова перебираться либо на ActiveAndroid, либо на ORMlite.
Хочу заметить, что public void onTerminate() на устройствах не вызывается.

Также стоит обратить внимание на ORM-компоненту DroidParts. Там схожий с ORMLite подход, но изначально ориентированный на Android.

Используются Cursorы. С одной стороны, упрощены запросы:

Cursor c = select().columns("_id", "name").where("year", Is.LESS, 1984).execute();

И с другой, есть EntityCursorAdapter c CRUD-методами и

public abstract void bindView(Context context, View view, EntityType item);,

где EntityType — это моделька, считанная из строки курсора c полями, необходимыми для отображения в ListView.
Но разве это хорошо, что HelperFactory.ReleaseHelper() вызывается в методе onTerminate() Application? Ведь даже в доках указано, что этот метод (onTerminate) не сработает на продакшн-девайсе.

public void onTerminate ()

This method is for use in emulated process environments. It will never be called on a production Android device, where processes are removed by simply killing them; no user code (including this callback) is executed when doing so.


Пруф

Как тогда лучше поступать? Всё-таки наследовать активность от OrmLiteBaseActivity?
Only those users with full accounts are able to leave comments. Log in, please.