Медленные функции в Android

Рейтинг: 0Ответов: 1Опубликовано: 24.04.2015

Подскажите как вызывать функции работающие продолжительное время. Например: для реализации окна авторизации, когда после нажатия кнопки "Login" программа может надолго зависнуть посылая запрос через интернет.

Ответы

▲ 2

Все операции , занимающие продолжительное время : загрузка/отправка по сети , обработка данных , сложные вычисления и пр. с длительностью более 5 секунд ( а на самом деле все , что хоть как то способно замедлить интерфейс ) , должно быть вынесено из основного (графического) потока в асинхронные . Андроид имеет собственную реализацию организации асинхронных потоков , которая позволяет эффективно взаимодействовать с основным (графическим) потоком , так как обращения напрямую к UI из других потоков невозможно . Это класс AsyncTask.

При реализации этого класса необходимо переопределить четыре метода:

doInBackground() - собственно здесь размещается код , который должен выполняться в асинхронном потоке.Он не имеет доступа к UI-потоку.

Следующие три метода , служат для взаимодействия с UI-потоком:
onPreExecute() – выполняется перед doInBackground()
onPostExecute() – выполняется после doInBackground()
onProgressUpdate() - выполняется в процессе выполнения асинхронной задачи. Здесь можно показывать промежуточные результаты , прогрессбар и тп.

Так же класс AsyncTask, естественно , может принимать параметры на обработку и возвращать обработанные данные .

Другим способом организации многопоточности в Android является классическая реализация Java - класс Thread для собственно открытия потока и класс Handler для его взаимодействия с главным (графическим) потоком.

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

Для организации "истинной многозадачности" необходимо использовать вместо вызова execute , вызов потока через executeOnExecutor , который не связан никакими ограничениями .

// обычный вызов
new MyAsyncTask().execute(); 

 //выполнение нескольких задач последовательно:
 new MyAsyncTask().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
 new MyAsyncTask().executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);


 //выполнение нескольких задач паралельно:
 new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
 new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);  

Так же в андроид есть более специализированные классы , выполняющие асинхронные задачи , например CursorLoader который асинхронно загружает курсор выборкой из БД и дополнительно управляет жизненным циклом курсора .

Если вы будете пытаться выполнять сетевые операции (работа с интернет) в главном потоке , то начиная с android 3.0 получите экзепшен android.os.NetworkOnMainThreadException , который не даст вам заниматься таким безобразием . Начиная с Honeycomb все сетевые операции должны выполняться только в дополнительном потоке и никак иначе.

Дополнительное чтение:

Оффициальная документация андроид по асинхронным потокам.
Пример работы с AsyncTask.
Пример работы с Thread в Андроид.
Что за проблемы с потоками в Андроид