Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Android client-server interaction

Android client-server interaction

Kirill Zotin

April 23, 2011
Tweet

More Decks by Kirill Zotin

Other Decks in Programming

Transcript

  1. Введение • Преимущества родных приложений над мобильными версиями сайтов •

    Специфика мобильных приложений: Document-ориентированая модель VS Database-ориентированная модель
  2. Преимущества над мобильными версиями сайтов. • Тесная интеграция с платформой

    • Улучшение поведения платформы • Фоновая работа • Более высокая скорость работы • "родной" пользовательский интерфейс
  3. Tips & Tricks • Выполняйте запросы к БД не в

    UI потоке • Используйте транзакции • Делайте код хорошо читаемым • Используйте Gzip сжатие • Android 3.0: Loaders • Удобный класс IntentService
  4. Выполняйте запросы к БД не в UI потоке • Используйте

    (Notifying)AsyncQueryHandler public class YourActivity extends Activity implements AsyncQueryListener { @Override public void onQueryComplete(int token, Object cookie, final Cursor cursor) { startManagingCursor(cursor); . . . } }
  5. Используйте транзакции @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(); }
  6. Группируйте детали запросов в одном месте Плохо Cursor mCursor =

    query(true, DATABASE_TABLE_EMAIL, new String[] { KEY_ROWID, KEY_EMAIL_NAME }, KEY_ROWID + "=" + rowId, null, null, null, null, null); if (mCursor.moveToFirst()) { long id = mCursor.getLong( mCursor.getColumnIndexOrThrow(KEY_ROWID)); String name = mCursor.getString( mCursor.getColumnIndexOrThrow(KEY_EMAIL_NAME)); } Хорошо interface ReviewsQuery { final String[] PROJECTION = new String[] { Reviews._ID, Reviews.TITLE, Reviews.SUBTITLE, Reviews.IMG_URL_SMALL, Reviews.ARTICLE_ID }; int ID = 0; int TITLE = 1; int SUBTITLE = 2; int IMG_URL = 3; int ARTICLE_ID = 4; String DEFAULT_SORT = Reviews.DATE + " desc"; } ... startAsyncQuery(QUERY_REVIEWS_ITEMS, null, Reviews.CONTENT_URI, ReviewsQuery.PROJECTION, selection, null, ReviewsQuery.DEFAULT_SORT); … final String url = getCursor().getString(ReviewsQuery.IMG_URL);
  7. Используйте сжатие 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); }
  8. 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); }
  9. Использование IntentService • Для обработки Intent стартует Service • Запрос

    обрабатывается в отдельном потоке • Параллельные запросы кладутся в одну очередь.
  10. Выводы • Не обрабатывайте сетевые операции в Activity, используйте Service

    • Сохраняйте данные часто • Все запросы к БД – в отдельный поток • Минимизируйте трафик сетевых операций • Используйте локальный кэш данных