Есть ли какой-нибудь способ на Android знать, если поток, выполняющий мой код, - это поток пользовательского интерфейса или нет? В качели было SwingUtilities.isEventDispatchThread()
сказать мне, есть ли я в потоке пользовательского интерфейса или нет. Есть ли какая-нибудь функция в Android SDK, которая позволяет мне это знать?
Как узнать, является ли этот поток потоком пользовательского интерфейса
Ответ 1
-
Ответ заимствован отсюда: Как проверить, не является ли текущий поток не основным потоком
Looper.myLooper() == Looper.getMainLooper()
-
В любом приложении Android есть только один поток пользовательского интерфейса, поэтому вы можете где-то в обратном вызове Activity, например onCreate(), проверить и сохранить его идентификатор, а затем просто сравнить этот идентификатор потока с сохраненным.
mMainThreadId = Thread.currentThread().getId();
-
В любом случае, вы можете опустить проверку, хотите ли вы что-то сделать в потоке пользовательского интерфейса и иметь любую ссылку на "Активность", используя
mActivity.runOnUiThread( new Runnable() { @Override public void run() { ... } });
который гарантированно работает на текущем потоке, если он UI, или поставлен в очередь в потоке пользовательского интерфейса.
Ответ 2
Да, есть способ. Проверьте текущий объект потока на предмет объекта основной лоппер. Основной петлитель всегда находится в потоке пользовательского интерфейса.
boolean isOnUiThread = Thread.currentThread() == Looper.getMainLooper().getThread();
Ответ 3
Hum фактически из-за архитектуры Android, все действия выполняются в основном потоке, то есть в потоке пользовательского интерфейса. Поэтому, когда вы кодируете действие, все, что находится в вашей деятельности, находится в потоке пользовательского интерфейса.
Вот почему в Honeycomb при добавлении сетевых вызовов в основной поток была добавлена ошибка: он полностью блокирует пользовательский интерфейс.
Итак, по умолчанию вы фактически работаете в потоке пользовательского интерфейса. Другое дело: если вы явно не попросите его быть в другом потоке, Служба будет работать в том же потоке, что и действия его приложения.
Итак, что делать?
- Когда вам нужно делать тяжелые вычисления в своей деятельности; одним из решений является использование AsyncTask (класс, разработанный, чтобы позволить вам легко использовать другой поток). Код в onExecute() запускается в другом потоке (но будьте осторожны при выполнении postExecute в основном потоке). Еще один - вручную запустить новый поток, когда AsyncTask на самом деле не адаптирован.
- Если вы создаете службу, которая выполняет дорогостоящие фоновые задачи, запустите ее в другом потоке с атрибутом android: process = ": my_process" манифеста. Вам нужно будет создать AIDL для связи с этой разделенной службой, но это не сложная задача.
- Многие объекты, такие как, например, MediaPlayer, имеют асинхронные варианты их методов. Старайтесь всегда использовать их.
Ответ 4
Поместите контрольную точку, где вы хотите проверить, и, когда она попадает, проверьте, можете ли вы взаимодействовать с вашим пользовательским интерфейсом (т.е. если пользовательский интерфейс не заморожен). Если вы не можете взаимодействовать с пользовательским интерфейсом, то вы находитесь в потоке пользовательского интерфейса, иначе вы находитесь в фоновом потоке.