Ваша проблема в том, что вы sleep()
на (или в противном случае блок) в потоке пользовательского интерфейса. Пожалуйста, поймите, что основной/пользовательский поток отвечает за перерисовку и обработку всех событий. Если вы сон там (onClick()
исполняется ионный поток пользовательского интерфейса), тогда Android не сможет сделать что-нибудь связанный с ним интерфейс пользователя.
Основой является то, что многопоточный графический интерфейс был бы крайне неэффективным. Большинство вызовов, связанных с пользовательским интерфейсом, таких как setBackground
, просто устанавливают некоторые данные или даже планируют некоторые другие действия, не имеют немедленного эффекта и будут давать результаты только в том случае, если элемент управления возвращается в основной контур управления потоком пользовательского интерфейса, например. для скоординированного перерисовки. Представьте себе, что произойдет, если вы запустите пару изменений макета один за другим, и каждый из них будет обработан немедленно - это приведет к огромному количеству вычислений, которые в следующий момент станут недействительными.
Таким образом, основной поток представляет собой не что иное, как огромный цикл обработки всех видов обратных вызовов, включая методы жизненного цикла Activity
, обратные вызовы прослушивателя событий и т. Д. Таким образом, пользовательский интерфейс является однопоточным, если вы это сделаете.
Что вам нужно сделать, так это выполнить долговременную работу на AsyncTask
или Thread. Для начала, я бы попробовал AsyncTask
. В методе onPostExecute()
AsyncTask, который снова запускается в потоке пользовательского интерфейса, вы можете управлять своим пользовательским интерфейсом по своему усмотрению.
Для быстрого успеха, вы можете также использовать тему:
@Override
public void onClick(View v) {
// on UI thread
btnTest.setImageResource(R.drawable.add);
// launch concurrent thread
(new Thread(new Runnable() {
@Override
// the code of this method will run concurrently
public void run() {
System.out.println("start");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
System.out.println("end");
// at this point, we need to get back to the UI thread
// for simplicity, we use the view's convenience method for that
v.post(new Runnable() {
@Override
// the code of this method will run on the UI thread
public void run() {
btnTest.setImageResource(R.drawable.del);
}
})
}
})
).start();
}
AsyncTask
выглядит гораздо лучше, но это не так легко создавать и использовать на лету.
Обратите внимание, что код, указанный выше, создает Thread
, который будет работать до тех пор, пока он не покинет свой метод run()
, или Android не уничтожит процесс Linux, на котором размещено ваше приложение.
Также обратите внимание, что в этой теме содержатся ссылки на множество объектов из вашего кода, так как он может получить доступ ко всему из своего окружения.
Вывод состоит в том, что если ваш поток работает в течение длительного времени, он может содержать ссылки на вид, который еще не виден, поэтому объекты памяти зомби могут ухудшить потребление ресурсов вашего приложения.
Кроме того, вы упомянули, что вы выполняете долговременную операцию. Вопрос в том, делает ли это операцию wait или делает это вычислить что-то. Если он что-то вычисляет, вы можете обнаружить, что он теперь занимает десять раз дольше, если вы не adjust the AsyncTask
/Thread
priority as described here.
так что это вы хотели ?? Измените «ImageButton» bg, когда пользователь нажимает кнопку и возвращает ее, когда он отпускает сенсорный экран? – Renjith
вы можете реализовать на сенсорном прослушивателе нажатие клавиши (кнопка нажата пользователем) и клавиша вверх (кнопка с пользователем) –