Книжная полка Сохранить
Размер шрифта:
А
А
А
|  Шрифт:
Arial
Times
|  Интервал:
Стандартный
Средний
Большой
|  Цвет сайта:
Ц
Ц
Ц
Ц
Ц

Эффективное использование потоков в операционной системе Android

Покупка
Артикул: 712462.02.99
Доступ онлайн
559 ₽
В корзину
Чтобы написать действительно полезное и удобное приложение для Android, то без многопоточности никак не обойтись, но как узнать о технологиях и методиках, которые помогут решить такую задачу? Книга с практической точки зрения описывает несколько асинхронных механизмов, доступных в программной среде Android SDK, а также рассматривает основные принципы и правила выбора одного из этих них, лучше всего подходящего для создаваемого приложения. Издание предназначено для программистов разной квалификации, уже работающих под Android и желающих улучшить качество создаваемых программ.
Ёранссон, А. Эффективное использование потоков в операционной системе Android : практическое пособие / А. Ёранссон ; пер. с англ. А. Снастина. - Москва : ДМК Пресс, 2018. - 312 с. - ISBN 978-5-97060-182-2. - Текст : электронный. - URL: https://znanium.com/catalog/product/2012515 (дата обращения: 02.05.2024). – Режим доступа: по подписке.
Фрагмент текстового слоя документа размещен для индексирующих роботов. Для полноценной работы с документом, пожалуйста, перейдите в ридер.
Эффективное  
использование потоков  
в операционной системе 
Android

Андерс Ёранссон

Efficient Android 
Threading

Anders Gо..ransson

Эффективное  

использование потоков  
в операционной системе 

Android

Москва, 2018

Андерс Ёранссон

УДК 004.451.9Android:004.451.2
ББК 32.972.11
 
Г11

 
 
Ёранссон А.

Г11 
Эффективное использование потоков в операционной системе 
Android / пер. с англ. А. Снастина. – М.: ДМК Пресс, 2018. – 
312 с.: ил. 

 
ISBN 978-5-97060-182-2

Чтобы написать действительно полезное и удобное приложение для Android, 

то без многопоточности никак не обойтись, но как узнать о технологиях и методиках, 
которые помогут решить такую задачу? Книга с практической точки зрения 
описывает несколько асинхронных механизмов, доступных в программной среде 
Android SDK, а также рассматривает основные принципы и правила выбора одного 
из этих них, лучше всего подходящего для создаваемого приложения.

Издание предназначено для программистов разной квалификации, уже работающих 
под Android и желающих улучшить качество создаваемых программ.

 
УДК  004.451.9Android:004.451.2

 
ББК 32.972.11

Все права защищены. Любая часть этой книги не может быть воспроизведена 
в какой бы то ни было форме и какими бы то ни было средствами без 
письменного разрешения владельцев авторских прав.

Материал, изложенный в данной книге, многократно проверен. Но поскольку 
вероятность технических ошибок все равно существует, издательство 
не может гарантировать абсолютную точность и правильность приводимых 
сведений. В связи с этим издательство не несет ответственности за возможные 
ошибки, связанные с использованием книги.

ISBN 978-1-449-36413-7 (анг.) 
Copyright © Anders Gоransson
..

ISBN 978-5-97060-182-2 (рус.) 
©  Оформление, перевод,  

 
 
ДМК Пресс

Посвящается Анне, Фабиану и Иде

Содержание

Предисловие............................................................13

Глава.1..Компоненты.ОС.Android.и.необходимость..
параллельных.вычислений..........................................19
Стек программной среды ОС Android ........................................................................19
Архитектура приложения ...............................................................................................21
Приложение .................................................................................................................21
Компоненты .................................................................................................................21
Activity ..................................................................................................................22
Service ....................................................................................................................24
ContentProvider..................................................................................................24
BroadcastReceiver ..............................................................................................25
Выполнение приложения ................................................................................................25
Процесс Linux .............................................................................................................25
Жизненный цикл .......................................................................................................26
Запуск приложения ..........................................................................................26
Завершение приложения ................................................................................27
Структурирование приложений для улучшения производительности .........29
Создание отзывчивых приложений с помощью потоков ............................30
Резюме ...................................................................................................................................32

Часть.I..Основы.........................................................33

Глава.2..Многопоточность.в.Java..................................34
Основы использования потоков ...................................................................................34
Выполнение .................................................................................................................35
Приложение с одним потоком ..............................................................................37
Многопоточное приложение .................................................................................37
Увеличение потребления ресурсов .............................................................38
Повышенная сложность ..................................................................................38
Нарушение целостности данных .................................................................38
Безопасное состояние потока ........................................................................................40
Внутренняя блокировка и монитор Java ...........................................................41
Синхронизация доступа к совместно используемым ресурсам ................43
Использование внутренней блокировки ...................................................43
Явное использование механизмов блокировки ......................................45
Пример: потребитель и производитель ..............................................................46
Стратегии выполнения задачи ......................................................................................48
Проектирование параллельного выполнения .................................................49
Резюме ...................................................................................................................................50

Содержание  7

Глава.3..Потоки.в.ОС.Android........................................51
Потоки приложения ОС Android .................................................................................51
UI-поток ........................................................................................................................51
Связующие потоки ....................................................................................................52
Фоновые потоки .........................................................................................................53
Процесс Linux и потоки ...................................................................................................53
Планирование .............................................................................................................57
Приоритет ............................................................................................................58
Управляющие группы ......................................................................................59
Резюме ...................................................................................................................................61

Глава.4..Взаимодействие.потоков................................62
Программные каналы .......................................................................................................62
Основы использования программного канала ................................................64
Пример: обработка текста в рабочем потоке ....................................................66
Совместно используемая память..................................................................................68
Механизм сигналов ...................................................................................................69
Блокирующая очередь BlockingQueue .......................................................................71
Передача сообщений в ОС Android .............................................................................73
Пример: простая передача сообщений ...............................................................74
Классы, используемые при реализации механизма передачи  
сообщений ....................................................................................................................77
Класс MessageQueue .........................................................................................77
Интерфейс MessageQueue.IdleHandler ......................................................79
Пример: использование интерфейса IdleHandler  
для завершения ненужного потока .............................................................80
Класс Message .............................................................................................................82
Состояние «инициализировано» .................................................................84
Состояние «ожидание» ...................................................................................85
Состояние «передано» .....................................................................................85
Состояние «готово к повторному использованию» ..............................85
Класс Looper ................................................................................................................86
Завершение работы объекта Looper ............................................................87
Объект Looper в UI-потоке ............................................................................88
Класс Handler ..............................................................................................................88
Создание и настройка ......................................................................................89
Создание сообщения ........................................................................................90
Вставка сообщения в очередь ........................................................................90
Пример: передача сообщений в двух направлениях .............................92
Обработка сообщений ......................................................................................95
Удаление сообщений из очереди ..........................................................................97
Наблюдение за очередью сообщений .................................................................99
Получение текущего состояния очереди сообщений ...........................99

 Содержание

Отслеживание обработки очереди сообщений .....................................102
Взаимодействие с UI-потоком ....................................................................................103
Резюме .................................................................................................................................104

Глава.5..Взаимодействие.между.процессами...............105
Механизм вызова удалённых процедур в ОС Android .......................................105
Объект Binder............................................................................................................106
Язык AIDL ..........................................................................................................................108
Синхронные вызовы удалённых процедур .....................................................110
Асинхронные вызовы удалённых процедур ...................................................113
Передача сообщений с использованием объекта Binder ....................................115
Однонаправленное взаимодействие .................................................................117
Взаимодействие в двух направлениях .............................................................119
Резюме .................................................................................................................................120

Глава.6..Управление.памятью....................................121
Сборка мусора ...................................................................................................................121
Утечки памяти, связанные с использованием потоков .......................................123
Выполнение потока .................................................................................................125
Внутренние классы .........................................................................................126
Статические внутренние классы ................................................................127
Рассогласование жизненных циклов ........................................................128
Взаимодействие потоков .......................................................................................131
Отправка сообщения с данными ................................................................132
Передача сообщения с задачей ...................................................................133
Устранение утечек памяти ............................................................................................134
Использование статических внутренних классов ........................................135
Использование слабых ссылок ...........................................................................135
Остановка рабочего потока ..................................................................................136
Переключение рабочих потоков .........................................................................136
Очистка очереди сообщений ...............................................................................136
Резюме .................................................................................................................................137

Часть.II..Механизмы.асинхронного.выполнения............138

Глава.7..Управление.жизненным.циклом.простого..
потока...................................................................139
Основы использования потоков .................................................................................139
Жизненный цикл .....................................................................................................139
Прерывания ...............................................................................................................141
Неперехватываемые исключения ......................................................................143
Управление потоком .......................................................................................................145
Определение и запуск потока ..............................................................................145
Анонимный внутренний класс ...................................................................145

Содержание  9

Общедоступный поток ..................................................................................146
Определение потока как статического внутреннего класса .............146
Обзор возможных вариантов выбора определения потока ..............147
Сохранение потока в рабочем состоянии ........................................................147
Сохранение потока в рабочем состоянии средствами класса  
Activity ................................................................................................................148
Сохранение потока в рабочем состоянии средствами класса 
Fragment..............................................................................................................151
Резюме .................................................................................................................................153

Глава.8..HandlerThread:.механизм.очереди..
сообщений.высокого.уровня......................................155
Основы использования HandlerThread ....................................................................155
Жизненный цикл HandlerThread ...............................................................................157
Случаи использования ...................................................................................................159
Повторяющееся выполнение задачи .................................................................159
Связанные задачи ....................................................................................................160
Пример: обеспечение надёжности данных с помощью 
SharedPreferences .............................................................................................160
Объединение задач в цепочку .............................................................................163
Пример: сетевые вызовы в цепочке задач ...............................................163
Вставка задач по условию .....................................................................................166
Резюме .................................................................................................................................167

Глава.9..Управление.выполнением.потока.средствами..
фреймворка.Executor...............................................168
Executor ...............................................................................................................................169
Пулы потоков ....................................................................................................................171
Предопределённые пулы потоков ......................................................................172
Пулы потоков, определяемые разработчиком ...............................................173
Конфигурация ThreadPoolExecutor .........................................................173
Проектирование пула потоков ............................................................................175
Определение размера .....................................................................................175
Динамические потоки в пуле ......................................................................177
Ограниченная или неограниченная очередь задач ..............................177
Конфигурация потока ....................................................................................178
Расширение возможностей ThreadPoolExecutor .................................179
Жизненный цикл .....................................................................................................180
Корректное завершение работы пула потоков ..............................................181
Варианты использования пула потоков и возникающие  
при этом сложности ................................................................................................183
Предпочтение отдаётся созданию потока, а не организации  
очереди ................................................................................................................183

 Содержание

Обработка предварительно подготовленных очередей задач ..........183
Опасная ситуация при нулевом количестве базовых потоков  
в пуле ...................................................................................................................184
Управление задачами ......................................................................................................184
Представление задачи ............................................................................................185
Добавление задач .....................................................................................................186
Заявление отдельной задачи .......................................................................187
Метод invokeAll ................................................................................................188
Метод InvokeAny .............................................................................................190
Отвергнутые задачи ................................................................................................191
ExecutorCompletionService ...........................................................................................191
Резюме .................................................................................................................................194

Глава.10..Связывание.фоновой.задачи.с.UI-потоком..
с.помощью.AsyncTask...............................................196
Основы использования класса AsyncTask ...............................................................196
Создание и начало работы ....................................................................................199
Отмена .........................................................................................................................200
Состояния ...................................................................................................................202
Пример: ограничение режима выполнения AsyncTask только  
одной задачей в любой момент времени .................................................203
Реализация AsyncTask ....................................................................................................203
Пример: загрузка изображений ..........................................................................204
Выполнение задачи в фоновом режиме ...................................................................207
Глобальная среда выполнения в приложении ...............................................209
Выполнение в разных версиях платформы ....................................................211
Настраиваемое выполнение .................................................................................213
Пример: неглобальное последовательное выполнение ......................213
Альтернативы AsyncTask ...............................................................................................214
Случаи излишне упрощённой реализации AsyncTask................................215
Фоновые задачи, для которых требуется объект Looper ...........................216
Локальная служба ...................................................................................................216
Использование метода execute(Runnable) ......................................................216
Резюме .................................................................................................................................217

Глава.11..Службы....................................................218
Причины использования служб для асинхронного выполнения ...................218
Локальные, удалённые и глобальные службы .......................................................220
Создание и выполнение .................................................................................................222
Жизненный цикл .............................................................................................................223
Запускаемая служба ........................................................................................................226
Реализация метода onStartCommand ...............................................................226
Повторный запуск ...................................................................................................227
Служба, управляемая пользователем ...............................................................230

Содержание  11

Пример: соединение по протоколу Bluetooth ........................................230
Служба, управляемая задачей .............................................................................234
Пример: параллельная загрузка .................................................................234
Подключаемая служба ...................................................................................................237
Локальное подключение .......................................................................................239
Выбор механизма асинхронного выполнения .......................................................242
Резюме .................................................................................................................................243

Глава.12..Класс.IntentService.....................................244
Основы использования IntentService .......................................................................244
Эффективные способы использования IntentService .........................................246
Задачи, выполнение которых должно быть последовательным .............246
Пример: взаимодействие с веб-службой .................................................246
Асинхронное выполнение в BroadcastReceiver .............................................249
Пример: периодически выполняемые длительные операции..........250
Сравнение IntentService и Service ..............................................................................252
Резюме .................................................................................................................................253

Глава.13..Доступ.к.провайдерам.контента.с.помощью.
AsyncQueryHandler...................................................254
Краткий обзор основ использования провайдеров контента ...........................254
Настройка ContentProvider для обработки в фоновом режиме ......................256
Использование AsyncQueryHandler..........................................................................258
Пример: список контактов с раскрывающимися элементами .................260
Как работает AsyncQueryHandler ......................................................................263
Ограничения ..............................................................................................................264
Резюме .................................................................................................................................265

Глава.14..Автоматическое.выполнение.в.фоновом..
режиме.с.помощью.загрузчиков.Loader.......................266
Фреймворк Loader ...........................................................................................................268
Класс LoaderManager .............................................................................................268
Сравнение методов initLoader() и restartLoader()...............................270
Интерфейс LoaderCallbacks .................................................................................272
Класс AsyncTaskLoader ..........................................................................................274
Надёжная загрузка данных с помощью CursorLoader ........................................275
Использование CursorLoader ..............................................................................275
Пример: список контактов ....................................................................................276
Добавление поддержки CRUD ...........................................................................277
Пример: использование CursorLoader вместе с обработчиком 
AsyncQueryHandler .........................................................................................278
Реализация специализированных загрузчиков .....................................................281
Жизненный цикл загрузчика ..............................................................................282
Фоновый режим загрузки .....................................................................................283

 Содержание

Пример: простой специализированный загрузчик ..............................284
Управление контентом ...........................................................................................286
Доставка кэшированных результатов ...............................................................287
Пример: специализированный загрузчик файлов .......................................288
Работа с несколькими загрузчиками ................................................................291
Резюме .................................................................................................................................292

Глава.15..Подведение.итогов:.выбор.механизма..
асинхронного.выполнения........................................294
Сохраняйте простоту ......................................................................................................295
Управление потоками и ресурсами ............................................................................296
Организация обмена сообщениями для улучшения отзывчивости ...............297
Как избежать неожиданного и нежелательного завершения задачи .............298
Простой доступ к провайдерам контента ................................................................299

Список.литературы..................................................301

Предметный.указатель.............................................304

Предисловие

Книга «Эффективное использование потоков в операционной сис-
теме Android» демонстрирует методы проектирования высокока-
чественных и надёжных в эксплуатации многопоточных приложений 
для операционной системы Android. В книге рассматриваются асин-
хронные механизмы, доступные в программной среде Android SDK, 
и соответствующие приемы создания быстрых, эффективных и пра-
вильно структурированных приложений.
Не вызывает сомнений, что без многопоточности немыслимо соз-
дание действительно полезных и удобных приложений, но ее при-
менение влечет увеличение сложности приложений и вероятности 
появления ошибок во время выполнения. Одна из причин этой проб-
лемы – трудности, непосредственно связанные с самим механизмом 
одновременной работы нескольких потоков, и другая причина – не-
рациональное использование возможностей платформы Android.
Цель этой книги – научить разработчиков приложений правильно 
выбирать требуемый асинхронный механизм, основываясь на полном 
понимании всех его достоинств и недостатков. При использовании 
правильно выбранного асинхронного механизма там, где он наиболее 
уместен, изрядная доля сложности перекладывается на программ-
ную платформу, при этом исходный код приложения становится бо-
лее простым для сопровождения и поддержки, а вероятность ошибок 
в нём снижается. Как правило, асинхронное выполнение не должно 
повышать сложность исходного кода сверх реальной необходимости, 
и этого можно добиться посредством разумного выбора асинхронного 
механизма из комплекта, предлагаемого в программной среде Android.
Несмотря на то что любой асинхронный механизм высокого уров-
ня уже с первого взгляда может показаться весьма удобным для 
практического применения, постоянно требуется не бездумное ис-
пользование, но глубокое его понимание, иначе в приложении будут 
возникать труднообъяснимые ошибки времени выполнения, сниже-
ние производительности или утечки памяти. Именно поэтому в книге 
содержатся не только практические рекомендации и примеры, но и 
подробные объяснения лежащих в их основе механизмов асинхрон-
ного выполнения.

Для. кого. предназначена. эта. книга
Эта книга предназначена для программистов на языке Java, уже зна-
комых с общими принципами программирования для платформы 

 Предисловие

Android. Здесь представлены методики, образующие прочную основу 
для написания надёжных и эффективных приложений с использова-
нием стандартных библиотек ОС Android.

Краткое. содержание. книги
Книга состоит из двух частей. В части I описываются основы много-
поточного программирования в ОС Android, то есть на языке Java, 
в Linux, с применением различных обработчиков, и их влияние на 
разработку приложений. В части II основное внимание уделено прак-
тическому применению многопоточности с более глубоким исследо-
ванием асинхронных механизмов, предоставляемых в распоряжение 
любому приложению.
В части I рассказывается, как программы на Java работают с пото-
ками. Программистам для ОС Android иногда приходится напрямую 
использовать библиотеки Java, поэтому понимание их возможностей 
важно для правильного применения конструкций более высокого 
уровня, описываемых в части II.
Глава 1 описывает устройство среды выполнения ОС Android и 
влияние различных компонентов типичного Android-приложения на 
использование многопоточности и параллельных вычислений.
Глава 2 рассматривает основы параллельного выполнения задач 
в языке Java.
Глава 3 обсуждает функционирование потоков в ОС Android и осо-
бенности выполнения  прикладных потоков в Linux, в том числе та-
кие важные темы, как планирование и управление группами потоков, 
а также их влияние на время ответной реакции приложения.
Глава 4 рассматривает основные механизмы обмена данными меж-
ду потоками, такие как совместно используемая (разделяемая) па-
мять, сигналы и широко применяемые сообщения ОС Android.
Глава 5 показывает, как ОС Android дополняет механизмы взаимо-
действия процессов, предоставляемые ядром Linux, такими механиз-
мами, как вызов удаленных процедур (RPC) и обмен сообщениями.
Глава 6 объясняет, как предотвращать утечки памяти в приложе-
ниях, которые могут приводить к существенному ухудшению рабо-
ты системы в целом, из-за чего пользователи, вероятнее всего, будут 
прос то избавляться от подобных приложений.
В части II рассматриваются библиотеки и программные конструк-
ции более высокого уровня, которые делают программирование с ис-
пользованием потоков более безопасным и простым.

Предисловие  15

Глава 7 описывает самую простую программную конструкцию под-
держки асинхронного выполнения – java.lang.Thread, а также обра-
ботку различных проблем и нестандартных ситуаций, которые могут 
возникать при её использовании.
Глава 8 демонстрирует удобный способ последовательного запуска 
задач в фоновом режиме.
Глава 9 предлагает вниманию читателя методики планирования, 
обработки ошибок и некоторые другие аспекты использования пото-
ков, такие как организация пулов потоков.
Глава 10 рассматривает AsyncTask, один из наиболее популярных 
механизмов асинхронного выполнения, а также правильное его при-
менение и пути обхода потенциальных сложностей.
Глава 11 описывает важный компонент Service, особенно полезный 
для обеспечения сразу нескольких приложений одними и теми же 
функциональными возможностями или для поддержки приложения 
в рабочем состоянии во время выполнения в фоновом режиме.
Глава 12 продолжает последнюю тему предыдущей главы описа-
нием эффективной методики запуска новых потоков выполнения из 
основного потока обслуживания графического пользовательского 
интерфейса.
Глава 13 посвящена механизму высокого уровня, упрощающему 
быстрый асинхронный доступ к компонентам типа ContentProvider.
Глава 14 объясняет, как обновлять компоненты графического 
пользовательского интерфейса с помощью загрузчиков (loaders) при 
асинхронной передаче новых данных вне зависимости от времени изменения 
их содержимого.
Глава 15 – итоговое резюме по всем методикам, описанным в книге, 
и обсуждение выбора приемов, наиболее подходящих для конкретного 
приложения. Здесь предлагаются правила и рекомендации, помогающие 
разработчику сделать правильный выбор.

Условные. обозначения. и. соглашения,. принятые.
в. книге
В книге используются следующие типографские соглашения:
Курсив используется для выделения важных положений, новых 
терминов, имён команд и утилит, а также имён файлов и каталогов.
Моноширинный шрифт используется для обозначения имён переменных, 
функций, типов, объектов и других программных конструкций 
и элементов исходного кода.

 Предисловие

Моноширинный курсив используется для обозначения в исходном коде 
или в командах шаблонных меток-заполнителей, которые должны 
быть заменены фактическими значениями.

 Так обозначается совет, указание или примечание общего характера.

 Эта пиктограмма предупреждает о неочевидных и обычно скрытых от не-
опытного разработчика «подводных камнях» и «ловушках», которых следует 
избегать.

Примеры. исходного. кода

Дополнительные материалы (примеры исходного кода, учебные 
задания и т. п.) можно получить по ссылке https://github.com/
andersgoransson/eatbookexamples.
Эта книга написана для того, чтобы помочь программистам в ра-
боте. Вообще говоря, вы можете использовать код из данной книги 
в своих программах и в документации. Если вы копируете для соб-
ственных нужд фрагмент исходного кода незначительного размера, 
то нет необходимости обращаться к автору и издателям для получе-
ния разрешения на это. Например, при включении в свою программу 
нескольких небольших фрагментов кода из книги вам не потребуется 
какое-либо специальное разрешение. Но для продажи или распро-
странения CD-диска с примерами из книг издательства O’Reilly не-
обходимо будет получить официальное разрешение на подобные дей-
ствия. При ответах на вопросы можно цитировать текст данной книги 
и приводить примеры кода из неё без дополнительных условий. При 
включении крупных фрагментов исходного кода из книги в докумен-
тацию собственного программного продукта также потребуется офи-
циальное разрешение.
Мы будем благодарны за добавление библиографической ссылки 
на источник при цитировании. Обычно ссылка состоит из названия 
книги, имени автора, наименования издательства и номера по ISBN-
классификации.
Если у вас возникли сомнения в легальности использования при-
меров исходного кода без получения специального разрешения при 
условиях, описанных выше, то без колебаний обращайтесь по адресу 
электронной почты: permissions@oreilly.com.
Примеры исходного кода из книги доступны по адресу: https://
github.com/andersgoransson/eatbookexamples.

Предисловие  17

Онлайн-сервис. Safari®. Books
Safari Books Online – это электронная библиотека, со-
держащая авторитетную информацию в виде книг и ви-
деоматериалов, созданных ведущими специалистами в области тех-
нологий и бизнеса.
Профессионалы в различных областях техники, разработчики программного 
обеспечения, веб-дизайнеры, бизнесмены и творческие 
работники используют Safari Books Online как основной ресурс для 
научных исследований, решения профессиональных задач, обучения 
и подготовки к сертификационным испытаниям.
Библиотека Safari Books Online предлагает широкий выбор продуктов 
и тарифов для организаций, государственных учреждений и 
частных лиц. Подписчики получают доступ к поисковой базе данных, 
содержащей информацию о тысячах книг, видеоматериалов и ещё 
не опубликованных рукописей от таких известных издательств, как 
O’Reilly Media, Prentice Hall Professional, Addison-Wesley Professional, 
Microsoft Press, Sams, Que, Peachpit Press, Focal Press, Cisco Press, 
John Wiley & Sons, Syngress, Morgan Kaufmann, IBM Redbooks, Packt, 
Adobe Press, FT Press, Apress, Manning, New Riders, McGraw-Hill, 
Jones & Bartlett, Course Technology, и многих других. Более подробную 
информацию о Safari Books Online можно получить на сайте 
https://www.safaribooksonline.com/.

От. издательства
Замечания, предложения и вопросы по этой книге отправляйте по 
адресу:

O’Reilly Media, Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
800-998-9938 (звонок из США или Канады)
707-829-0515 (международный или местный звонок)
707-829-0104 (факс)

или по электронной почте:

bookquestions@oreilly.com

Cписок опечаток и ошибок, файлы с примерами и другую дополнительную 
информацию можно найти по адресу: http://bit.ly/efficient-
android-threading.

Доступ онлайн
559 ₽
В корзину