mobile fest#spb 2012

Post on 16-Jun-2015

350 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Секреты удобного хранения данных

TRANSCRIPT

Android:Секреты удобного хранения данных

Дмитрий Викторович МалыхановDataArt

http://www.dataart.com/

● Shared Preferences● Internal/External Storage● SQLite Databases

● Content Provider

Способы хранения данных

http://goo.gl/r673r

● Унифицированный интерфейс● Асинхронные уведомления● Маскировка деталей реализации● Прозрачное хранение файлов● Безопасность● Работа в отдельном процессе

ПреимуществаContent Provider

● IPC вызовы (marshalling)● Кажущееся усложнение кода● Надуманные проблемы с транзакциями

Осложнения

"Вечный" сервис

SQLite Динамическая типизация(читайте: строковые данные)

"Под капотом"

http://goo.gl/igQqT

Инициализация должна быть БЫСТРОЙ!

см. ContentProvider.onCreate() javadoc

Оптимизация:Шаг первый

http://goo.gl/pdBY5

Разгружаем UI thread:

Избегайте лишних преобразований типов!

Оптимизация:Шаг второй

Практически бесполезно

рекомендация:только в сочетании с CASCADE

Оптимизация:Внешние ключи

VIEW вместо сложных JOIN'ов

значительное упрощение кода

Оптимизация:Соединения

Все обращения кContentProvider вне UI thread!

AsyncTask, Handler,AsyncQueryHandler

LoaderManager

Оптимизация:AsyncQueryHanlder

http://goo.gl/1fpOi

Категории:● Item● Directory

Идентификатор категории в ID UriMatcher'а

Оптимизация:Упрощение кода

http://goo.gl/A1wqF

int MASK_TYPE = 0x0000000F;

int TYPE_ITEM = 0x00000001;

int TYPE_DIR = 0x00000002;

...

switch (matcher.match(uri) & MASK_TYPE) {

case TYPE_ITEM:

return "vnd.android.cursor.item/NAME";

case TYPE_DIR:

return "vnd.android.cursor.dir/NAME";

...

Пример:Категории в ID

Зачастую данные изменяются только на сервере:

int rows = resolver.update(...)

if (0 == rows) {

resolver.insert(...);

}

Оптимизация:Конфликты

SQLiteDatabase:

public long insertWithOnConflict (String table,

String nullColumnHack,

ContentValues initialValues,

int conflictAlgorithm)

SQLiteDatabase.CONFLICT_REPLACE

API 8+

Разрешение конфликтов

http://goo.gl/dU1fo

Архитектурные проблемы!

Загрузите XML/CSV в Provider:

ContentResolver.openOutputStream(uri, mode)

ContentProvider.openFileDescriptor(uri, mode)

Большой импорт:Маскировка проблем

http://goo.gl/UlJInhttp://goo.gl/VOF9m

Batch Access:

ContentProviderResult[] applyBatch (String authority, ArrayList<ContentProviderOperation> operations)

Расход памяти!

Большой импорт:Решение

http://goo.gl/1AX8Q

android.net.Uri:● scheme● authority● path● fragment● query

Вся сила URI

http://goo.gl/bSwjG

Перерасход ресурсов UI thread

Решение:Пропускать ненужные уведомления

Content Provider:Уведомления

final static String FRG_SKIP_NOTIFY =

"skip-notify";

...

private boolean isNotifyRequired(Uri uri) {

return !FRG_SKIP_NOTIFY.equals(

uri.getFragment());

}

Пропускаем уведомления (1/3)

public int update(Uri uri, ...) {

...

int rows = ... update ...;

if (rows > 0 && isNotifyRequired(uri)) {

resolver.notifyChange(uri, null);

}

...

Пропускаем уведомления (2/3)

// client code, e.g. your networking service

Uri uri = ... Uri.Builder ...

.fragment(FRG_SKIP_NOTIFY);

...

// build batch of ops with uri

resolver.applyBatch(...);

resolver.notifyChange(uri, null);

Пропускаем уведомления (3/3)

http://goo.gl/FLbVX

Дополнительные данные:

Uri:● fragment● query

ContentResolver:● openOutputStream

Оптимизация:Шаг последний

Android:Секреты удобного хранения данных

ВОПРОСЫ ?

Android:Секреты удобного хранения данных

Дмитрий Викторович МалыхановDataArt

http://www.dataart.com/

top related