Как отправлять обратные вызовы в Android в любой произвольный поток

Я использую игровой движок Unity, который также поддерживает экспорт в Android.

Механизм использует несколько потоков, включая поток пользовательского интерфейса и отдельный поток сценариев, в котором выполняется весь пользовательский код.

Мой сценарий требует, чтобы я вызывал некоторую операцию в фоновом потоке, и я хотел бы маршалировать результат обратно в основной поток сценариев.

Я знаю основы AsyncTask, Executor и Лупер. Из них Looper кажется хорошим кандидатом, поскольку он позволяет настроить очередь и отправлять обратные сообщения в заданный поток (AsyncTask «зашит» для запуска обратного вызова в потоке пользовательского интерфейса, чего я здесь не хочу).

Каков правильный способ достижения этого?


person lysergic-acid    schedule 23.11.2014    source источник
comment
Обработчик поможет вам вызвать операцию в фоновом потоке.   -  person Shriram    schedule 23.11.2014
comment
Как насчет пользовательского BroadcastReceiver?   -  person Don Chakkappan    schedule 23.11.2014
comment
@DonChakkappan Я считаю, что Handler сделает это, как было предложено в комментарии выше. Я не работал с ним, но я проверю документацию для этого класса.   -  person lysergic-acid    schedule 23.11.2014


Ответы (1)


Существует 3 основных способа взаимодействия с потоком пользовательского интерфейса:

  1. Activity.runOnUiThread(Runnable)

  2. View.post(Runnable)

  3. Обработчики

В вашем случае я советую вам создать Handler, так как 2 первых решения подразумевают, что у вас есть ссылка на ваш Activity или View

Изменить

Если вы хотите использовать любой поток в своем приложении, просто убедитесь, что установлен Looper, и используйте связанный Handler

class YourLooperThread extends Thread
{
    // make it accessible from the outside
    private Handler handler;

    @Override public void run()
    {
        Looper.prepare();

        // Customize your handler, it has to be used in any thread which want to push a message in this thread's looper message Queue
        handler = new Handler();

        Looper.loop();
    }
}

Будьте осторожны: все остальные задачи, которые вы хотите выполнить в этом потоке, должны выполняться через очередь сообщений, т. е. публиковать исполняемый объект в обработчике. Дополнительная информация здесь: Handlers, MessageQueue, Looper, все ли они выполняются в потоке пользовательского интерфейса?

person ToYonos    schedule 23.11.2014
comment
Спасибо. В моем вопросе особо упоминалось, что я не хочу выполняться в потоке пользовательского интерфейса, а в любом произвольном потоке в процессе. - person lysergic-acid; 23.11.2014
comment
Спасибо. Нужно ли это помещать в пользовательский класс Thread? ситуация, которую я имею, - это поток, который уже был создан фреймворком. Могу ли я добавить к этому обработчик и Looper и предоставить обработчик другим потокам для публикации? Кроме того, что вы подразумеваете под всеми задачами, которые должны выполняться через очередь сообщений? - person lysergic-acid; 24.11.2014
comment
Этот вопрос поможет вам понять: stackoverflow.com/questions/ 6984263/ Looper, когда он зацикливается, блокирует ваш поток, поэтому он не сможет выполнять никакие другие операции. Если этот поток исходит из фреймворка, это может быть проблемой. - person ToYonos; 24.11.2014