2. Введение
• Преимущества родных приложений над
мобильными версиями сайтов
• Специфика мобильных приложений:
Document-ориентированая модель
VS
Database-ориентированная модель
3. Преимущества над мобильными
версиями сайтов.
• Тесная интеграция с платформой
• Улучшение поведения платформы
• Фоновая работа
• Более высокая скорость работы
• "родной" пользовательский интерфейс
12. Tips & Tricks
• Выполняйте запросы к БД не в UI потоке
• Используйте транзакции
• Делайте код хорошо читаемым
• Используйте Gzip сжатие
• Android 3.0: Loaders
• Удобный класс IntentService
13. Выполняйте запросы к БД
не в UI потоке
• Используйте (Notifying)AsyncQueryHandler
public class YourActivity extends Activity implements AsyncQueryListener {
@Override
public void onQueryComplete(int token, Object cookie,
final Cursor cursor) {
startManagingCursor(cursor);
. . .
}
}
14. Используйте транзакции
@Override
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
throws OperationApplicationException {
final SQLiteDatabase db = mDatabaseHelper.getWritableDatabase();
db.beginTransaction();
try {
final int numOperations = operations.size();
final ContentProviderResult[] results = new ContentProviderResult[numOperations];
for (int i = 0; i < numOperations; i++) {
results[i] = operations.get(i).apply(this, results, i);
}
db.setTransactionSuccessful();
return results;
} finally {
db.endTransaction();
}
15. Группируйте детали запросов
в одном месте
Плохо Хорошо
Cursor mCursor = query(true, interface ReviewsQuery {
DATABASE_TABLE_EMAIL, final String[] PROJECTION = new String[] {
Reviews._ID,
new String[] { Reviews.TITLE,
KEY_ROWID, KEY_EMAIL_NAME Reviews.SUBTITLE,
}, Reviews.IMG_URL_SMALL,
KEY_ROWID + "=" + rowId, Reviews.ARTICLE_ID
null, null, null, null, null); };
int ID = 0;
int TITLE = 1;
if (mCursor.moveToFirst()) { int SUBTITLE = 2;
long id = mCursor.getLong( int IMG_URL = 3;
mCursor.getColumnIndexOrThrow(KEY_ROWID)); int ARTICLE_ID = 4;
String name = mCursor.getString(
String DEFAULT_SORT = Reviews.DATE + " desc";
mCursor.getColumnIndexOrThrow(KEY_EMAIL_NAME)); }
} ...
startAsyncQuery(QUERY_REVIEWS_ITEMS, null,
Reviews.CONTENT_URI,
ReviewsQuery.PROJECTION,
selection, null,
ReviewsQuery.DEFAULT_SORT);
…
final String url =
getCursor().getString(ReviewsQuery.IMG_URL);
16. Используйте сжатие Gzip
HttpGet request = new HttpGet(uri);
request.addHeader("Accept-Encoding", "gzip");
HttpResponse response = getHttpClient().execute(request);
Header contentEncoding = response.getFirstHeader("Content-Encoding");
if (contentEncoding != null &&
contentEncoding.getValue().equalsIgnoreCase("gzip")) {
is = new GZIPInputStream(is);
}
17. Honeycomb API: CursorLoader
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getLoaderManager().initLoader(0, null, this);
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
final String eventId = getArguments().getString(EXTRA_EVENT_ID);
return new CursorLoader(getActivity(),
Events.CONTENT_URI,
EventQuery.PROJECTION,
EventQuery.SELECTION, new String[] {eventId}, null);
}
18. Использование IntentService
• Для обработки Intent стартует Service
• Запрос обрабатывается в отдельном потоке
• Параллельные запросы кладутся в одну
очередь.
19. Выводы
• Не обрабатывайте сетевые операции в
Activity, используйте Service
• Сохраняйте данные часто
• Все запросы к БД – в отдельный поток
• Минимизируйте трафик сетевых операций
• Используйте локальный кэш данных