Почему invalidate должен вызываться потоком пользовательского интерфейса

#java #android

#java #Android

Вопрос:

Кто-нибудь знает, почему invalidate должен вызываться потоком пользовательского интерфейса?

Как и в Java Swing, repaint функция может вызываться как потоком, отличным от пользовательского интерфейса, так и потоком пользовательского интерфейса. repaint выполняет очень похожую задачу, как invalidate (этот метод вызывает вызов метода paint этого компонента как можно скорее. В противном случае этот метод вызывает вызов метода обновления этого компонента как можно скорее.).

Комментарии:

1. Лично я думаю, что этот вопрос «недооценен». Я также думал об этом вопросе, и я пришел к выводу, что причиной является синхронизация. Если вы обновите (перерисуете) Пользовательский интерфейс только из 1 потока, тогда нет причин выполнять синхронизацию. Представьте сценарий: в thread1 вы проверяете TextView на равенство некоторой строке «text», в случае успеха вы меняете TextView на «text» «1». Но в то же время thread2 мог бы изменить содержимое на «text2», и вы могли бы получить «text21», что не то, что вы хотели. Итак, нет необходимости синхронизировать. Другие значения?

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

Ответ №1:

Нет, они не совпадают. В Swing также существует метод invalidate , и для этого также требуется, чтобы вызывающий вызывал его из EDT / Swing / UI-thread.

Похоже, эквивалентом перерисовки на Android является postInvalidate

Ответ №2:

Когда мы вызываем invalidate из UIThread, он сообщает приложению перерисовать представление, когда основной поток простаивает.Итак, когда мы вызываем invalidate , он в основном планирует повторное отображение представлений после завершения всей остальной непосредственной работы.Если вы хотите перерисовать представление в отдельном потоке, отличном от UIThread, тогда используйте postInvalidate() .