AsyncTask - это стандартный способ асинхронного выполнения длительных операций в фоновом потоке без удержания потока пользовательского интерфейса. Не следует выполнять какие-либо взаимодействия с пользовательским интерфейсом из метода doInBackground ().
Мой вопрос: Какие примеры взаимодействия с пользовательским интерфейсом запрещены? Будет ли это любое из следующего:
- LayoutInflater.inflate ()
- View.findViewById ()
- TextView.setText ()
Я склонен сказать да, но сейчас у нас есть некоторый код, который выполняет все эти (и более) и вызывается из метода doInBackground (), и все же код работает. Я видел, как другие люди указывали, что они получают исключение при попытке выполнить действие пользовательского интерфейса от doInBackground (), но это не наш опыт.
Наш код создает отчет на экране, который не отображается доВся операция завершена. В редких случаях (трудно воспроизвести) при попытке отменить операцию очень быстро мы увидим, что приложение переходит в странное состояние, но оно не падает.
Перед изменением нашего кода в надежде найти этоВ редких случаях я хотел узнать, есть ли у кого-нибудь мысли о том, почему наш код «работает» как есть.
Единственный другой полезный кусочек информации - это то, что наш метод doInBackground имеет следующий шаблон кода. :
protected Boolean doInBackground(Void... voids) {
if (null == Looper.myLooper()) {
Looper.prepare();
}
publishProgress(0.0);
// Perform ui/non-ui logic here
Looper myLooper = Looper.myLooper();
if (null != myLooper && Looper.getMainLooper() != myLooper) {
myLooper.quit();
}
return true;
}
Looper необходим для некоторого кода генерации отчетов (опущен), который использует new Handler () для генерации данных. Я не уверен, что создание Looper каким-то образом делает наши пользовательские взаимодействия легальными.
(У меня есть трассировка стека, которая четко показывает, как наша пользовательская активность вызывается из doInBackground, на случай, если вы подумали, что мы можем отключитьсянесколько отдельных тем для обновления нашего интерфейса)