Как узнать, является ли этот поток потоком пользовательского интерфейса

Есть ли какой-либо способ на Android знать, если поток, выполняющий мой код, является потоком пользовательского интерфейса или нет? В swing был SwingUtilities.isEventDispatchThread() чтобы сообщить мне, есть ли я в SwingUtilities.isEventDispatchThread() пользовательского интерфейса или нет. Есть ли какая-нибудь функция в Android SDK, которая позволяет мне это знать?

  1. Ответ заимствован отсюда: как проверить, не является ли текущий поток не основным потоком

    Looper.myLooper() == Looper.getMainLooper()

  2. Любое приложение для Android имеет только один поток пользовательского интерфейса, поэтому вы можете где-то в обратном вызове Activity, например onCreate (), проверить и сохранить его идентификатор, а затем просто сравнить идентификатор потока с сохраненным.

    mMainThreadId = Thread.currentThread().getId();

  3. В любом случае, вы можете опустить проверку, хотите ли вы что-то сделать в потоке пользовательского интерфейса и иметь любую ссылку на «Активность», используя

     mActivity.runOnUiThread( new Runnable() { @Override public void run() { ... } }); 

Который гарантированно работает на текущем потоке, если это пользовательский интерфейс, или поставлен в очередь в потоке пользовательского интерфейса.

Да, есть способ. Проверьте текущий объект потока на объект потока основного лопера. Основной петлитель всегда находится в потоке пользовательского интерфейса.

 boolean isOnUiThread = Thread.currentThread() == Looper.getMainLooper().getThread(); 

Hum фактически из-за архитектуры Android, все действия выполняются в основном потоке, то есть в потоке пользовательского интерфейса. Поэтому, когда вы кодируете действие, все, что находится в вашей деятельности, находится в потоке пользовательского интерфейса.
Вот почему в Honeycomb при добавлении сетевых вызовов в основной поток была добавлена ​​ошибка: он полностью блокирует пользовательский интерфейс.

Поэтому по умолчанию вы фактически работаете в потоке пользовательского интерфейса. Другое дело: если вы явно не попросите его быть в другом потоке, Служба будет работать в том же потоке, что и действия его приложения.

Так что делать ?

  • Когда вам нужно делать тяжелые вычисления в своей деятельности; Одним из решений является использование AsyncTask (класс, разработанный, чтобы позволить вам легко использовать другой поток). Код в onExecute () запускается в другом потоке (но будьте осторожны при выполнении postExecute в основном потоке). Другой – вручную запустить новый поток, когда AsyncTask на самом деле не адаптирован.
  • Если вы создаете службу, которая выполняет дорогостоящие фоновые задачи, запустите ее в другом потоке с атрибутом android: process = ": my_process" манифеста. Вам нужно будет создать AIDL для связи с этой разделенной службой, но это не сложная задача.
  • Многие объекты, такие как, например, MediaPlayer, имеют асинхронные варианты их методов. Старайтесь всегда использовать их.

Поместите контрольную точку, где вы хотите проверить, и, когда она попадает, проверьте, можете ли вы взаимодействовать с вашим пользовательским интерфейсом (т. Е. Если пользовательский интерфейс не заморожен). Если вы не можете взаимодействовать с пользовательским интерфейсом, то вы находитесь в потоке пользовательского интерфейса, иначе вы находитесь в фоновом потоке.