Multithread

**********************************************************

Данный текст - конспект книги Efficient Android Threading (для короткого ознакомления можно прочитать последнюю главу с итогами:page:294-300 )

Эта диаграма отображает основные описанные тут элементы:

***********************************************************

Multithreading: sync (ReentrantReadWriteLock, Semaphore)

PipedReader and PipedWriter in Java

Android: Looper & Handler

  • IdleHandler - слушатель для простоя потока с handler. Можно загружать простой, а можно просто закрыть поток.
    • Печать информации об очереди сообщений:
      • единоразово: mHandler.dump(new LogPrinter(Log.DEBUG, "TAG"), "PREFIX");
    • постоянно: Looper.getMainLooper().setMessageLogging(new LogPrinter(Log.DEBUG, TAG));
    • Looper UI потока доступен отовсюду: Looper.getMainLooper()

Services: Process interaction

Executors(page:168)

    • Executors:
      • Executors.newFixedThreadPool(n) (page:172)
      • Executors.newCachedThreadPool() - лимитированое средой число потоков. (page:172)
      • Executors.newSingleThreadPool() ~= Executors.newFixedThreadPool(1) (page:173)
      • ThreadFactory as instrument thread creation by Executors (page:178)
      • Executor has methods: beforeExecute(Thread, Runnable), afterExecute(Runnable, Thread), terminated() (page:179)
    • ExecutorService (extends Executor) work with Callable too
    • RejectedExecutionHandler - обработка отвергнутых задачь (page:191)
    • ExecutorCompletionService - Контроль выполнения ряда заданий (пример с загрузчиком картинок и их показом сразу после загрузки: page:191)

AssyncTask (наглядный пример загрузки картинок page:204-207)

    • execute(Params...) - выполенение синхронно/асинхронно в зависемости от версии платформы
    • static execute(Runnable) - последовательное
    • executeOnExecutor(Executor, Params...) - настраиваемое
    • особенности:
      • Простая реализация, много параметров, доступ обновлению в UI птоке
      • использует всегда одни раз иничиализированные потоки длявыполдения
      • "неконтролируемость" паралельности и как следствие влияние на другие задачи других AssyncTask
      • можно привязывать к общим Executors в разных Activity/Services
      • в сервисах мало полезен, так как может тормозить остальные задачи
      • НАИБОЛЕ ПОЛЕЗЕН В Activity

Service (page:218)

  • для фоновых задачь:
      • Помним, что это UI поток
      • Более регулируемый жизненный цыкл
      • Более высокий приоритет
    • Виды Service(page:220-221):
      • Локальный (private in the same process)
      • Удаленная закрытая (private in the other process)
      • Удаленная открытая (public in the other app&pricess)
    • Метод onStartCommand() возвращает значение, определяющее поведение сервиса при принудительной остановке его системой(page:227-229)
    • Bind Service (page:237-242)
    • IntentService - последовательное выполнение задачь в work потоке
    • AssyncTask в Service - плохая дея, так как среда выполнения AssyncTask одна для всего процесса. Даже, если он асинхронный, влияние может быть.
    • BroadCastReceiver
      • Может выполнять длительные операции в IntentService, даже, если будет удален за неактивность. (page:249)
      • Есть подход с продлением жизни receiver через goAsync() (after API level 11 - page:250)

ContentProvider (page:254-258)

    • AssyncQueryHandler - помогает делать запрос ContentProvider в асинхронном режиме(page:258+)
      • пример 2х уровневого запроса (page:260-263)
  • CursorLoader...

Loader (пример-шаблон page:269)

    • Advantages: (page:267)
    • Асинхронная обрабтка данных
    • Управлением жизненным циклом
    • Кеширование данных, активити пересоздается прямо сейчас
    • Защита от утечек памяти
    • Основные методы: (page:270-271)
    • void onCreateLoader(int id, Bundle args)
    • Loader<D> onLoadFinished(Loader<D> loader, D data)
    • void onLoaderReset(Loader<D> loader)
  • Инициализация: (page:270-271)
    • initLoader - повторно использует доступный загрузчик. Если данные уже загружены, то просто вернет закешированный ранее резулльтат.
    • restartLoader - удаляет старый загрузчик и кеш его данных и создает новый.
    • CursorLoader (see example on page:276-277)
      • работает только в ContentProvider
      • делает только запросы на считывание.
    • CursorLoader можно использовать для загрузки и обновления данных по их изменению с помощью AssyncQueryHandler (see example on page:278-281)
  • Можно написать свой Loader, но прийдется реализовать кешиование, контроль данных и возврат результата (see example on page:288-291)

Источник конспекта: Андерс Ёранссон. Эффективное использование потоков в операционной системе Android.

(Efficient Android Threading)