2. У каждого android-приложения есть свой
главный поток (UI Thread)
● В нем выполняются операции жизненного цикла activity, отрисовки
интерфейса, обработка событий от пользователя и т.д
● Графический интерфейс является потоко-небезопасным. Попытка
вызвать методы View не из главного потока приводит к исключению
● Если какая-нибудь операция выполняется в главномпотоке более 5
секунд, то появится ANR (Application Not Responding) диалог, с
предложением пользователю убить ваше приложение =(
3. Начиная с Android 3.0 появился StrictMode, который валит приложение,
если разработчик сделал что-то не так. Полез в интернет из главного
потока? Захотел прочитать файл? Получай исключение!
Мораль
Ни когда не выполняйте долгих операций в главном потоке!
4.
5. Механизмы для асинхронного поведения
● Thread/Executor т.е все что есть в Java.
● Handler - позволяет работать с очередью сообщений,
ассоциированной с потоком.
● AsyncTask - наверное, самый часто используемый компонент для
создания асинхронного поведения
● Service/IntentService - не имеют ui, работают как фоновые процессы
● Loader - еще один механизм для запуска асинхронных задач,
появился с API level 11
7. AsyncTask
Очень часто задача, предполагающая асинхронность выглядит так:
1. Сделать что то в UI потоке, например вывести диалог начала загрузки
2. Начать выполнять задачу в background поток, походу выполнения,
может быть, что-то обновлять в UI потоке (например статус прогресса
загрузки)
3. По завершению загрузки, что-то сделать в UI потоке, например
вывести диалог о удачном завершении задачи.
10. AsyncTask
В зависимости от версии android-а execute() для AsyncTask будет
работать по разному:
● 1.6 < API < 3.2 — на запуск новой AsyncTask будет выделяться новый
поток
● API ≥ 3.2 — на запуск всех AsyncTask используется по умолчанию
один поток, но добавили поле AsyncTask.THREAD_POOL_EXECUTOR
12. ● Появились в API 11 (Android 3.0)
● Привязаны к методам жизненного цикла activity или fragment-а
● Крайне рекомендуется использовать только с cursor-ми (Cursor loader)
Loader
Основные компоненты
● LoaderManager - управляет Loader-ами (создает, уничтожает,
стартует)
● LoaderManager.LoaderCallabacks - интерфейс для связи клиента и
менеджера
● Loader - объект, асинхронно выполняющий задачу
13. Работа с сетью
● Чаще всего под работой с сетью подразумевают взаимодействие с
REST-подобными сервисами т.е это HTTP + JSON/XML
● Для доступа в сеть в вашем манифесте должен быть прописан
android.permission.INTERNET
● Для отображения web-страниц в вашем приложении можно
использовать WebView - практически полноценный браузер
Стандартные средства
● HttpClient
● HttpUrlConnection
● OkHttp / Retrofit
14. Типичный use-case
• Создаем HttpClient (DefaultHttpClient или AndroidHttpClient)
• Создаем и настраиваем запрос – объект класса HttpUriRequest (обычно
HttpGet или HttpPost)
• Выполняем запрос HttpClient.execute и получаем в
ответ HttpResponse
• Разбираем HttpResponse – хедеры, строку ответа и т.д.
• Получаем HttpEntity и разбираем тело ответа
HttpClient
15. HttpUrlConnection
Типичный use-case
• Создаем объект URL, зовем openConnection() и кастуем
к HttpURLConnection
• Подготавливаем запрос – устанавливаем хедеры,
параметры запроса, тип контента и т.д.
• По необходимости подготавливаем тело запроса (POST
запрос). setDoOutput(true) и getOutputStream()
• Читаем ответ сервера. Строку ответа (код, сообщение),
хедеры, cookie и т.д.
• Закрываем соединение и освобождаем все ресурсы
16. • Ребята из android команды утверждают, что и там и там
есть куча багов
• В android 2.3+ багов меньше в HttpUrlConnection
• В предыдущих версиях – в HttpClient
• О каких именно багах идет речь – да кто бы знал
• С HttpClient’ом приятнее работать
HttpUrlConnection vs HttpClient
17. ● OkHttp - библиотека для работы с http от компании Square.
● Retrofit - библиотека для работы с REST API от компании Square, на
Android по умолчанию использует HttpUrlConnection, но лучше
подключать OkHttp из-за ошибок в последнем.
OkHttp / Retrofit
18. Проблемы
1. Асинхронность через callback-и очень скоро порождает высокую
степень вложенности (AsyncTask-а в AsyncTask-e), что резко снижает
читабельность и сопровождаемость кода.
2. Кроме REST API, нам также постоянно приходится скачивать картинки
и делать это приходится в adapter-ах к ListView.
3. Почти к любому backend-у необходимо выстраивать кэш на стороне
приложения.
4. Часто результат выполнения сетевых запросов нужен не только в том
месте, откуда они были вызваны
Решения
1. Netflix/rxJava
2. Square/picasso
3. ??? (ORM*, сохранние json/xml в файлы, черт знает что еще)
4. Square/Otto
19. 1. http://www.slideshare.net/andersgoransson/efficient-android-threading -
презентация по асинхронности (лучше этой)
2. http://www.vogella.com/tutorials/AndroidServices/article.html - более
подробно про Service
3. https://github.com/Netflix/RxJava - библиотека для “реактивного”
программирования на Java
4. https://github.com/square/picasso - android библиотека для загрузки
изображений из сети
5. https://github.com/square/retrofit - библиотека для работы с REST API
6. https://github.com/noveogroup/university-android-task6 - примеры по ходу
текущей лекции
7. https://github.com/tttzof351/SmsReader - пример с loader-ом
Что еще почитать/посмотреть?
20. 1. Реализовать экран StudentTaskActivity, показывающий список*
заголовков новостей http://androidtraining.noveogroup.com/news/getAll
2. Пока новости загружаются, пользователю должен быть показан
ProgressDialog
3. Использовать AsyncTask или Service для реализации асинхронного
поведения
4. Формат ответов можно посмотреть http://androidtraining.noveogroup.
com/main/requestFormat
* Можно так же показывать в элементах списка картинки, используя
square/picasso
Задание