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()
- Печать информации об очереди сообщений:
- Маршализация - серриализация не только данных, но и програмного кода для отправки/выполнения в другом процессе
- Отличие потока от процесса: процесс имеет свою память.
- Binding:
- обрабатывается связующими потоками
- может быьт синхронным и асинхронным ()
- AIDL (Android Interface Definition Language) - создание интерфейса взоимодействия с сервисом в другом приложении (Стр.108)
- Требуется синхронизация обработки
- Запрос "залипает" до ответа
- Как решение возможно использование методов с дескриптором oneway, которые не "залипают" (pages:109-110)
- Отправка сообщений в другой процесс/Service с помощю объекта Binder(стр.115)
- Простое взаимодействие между процессами: возможно Однонаправленно(стр.117) и Двунаправленно(стр.119)
- Обработка сообщений только в 1-м потоке и получение тоже только в 1-м
- Thread and Activity recreation
- Save by Activity methods: onRetainNonConfigurationInstance/getLastNonConfigurationInstance
- Create Fragment for keep Thread Only (pages: 151-153)
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
- ExecutorService.invokeAll (page:188)
- ExecutorService.invokeAny (page:190)
- 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)
- Можно использовать несколько Loader-ов одновременно (see example on page:291-292)