Остановка потока обработчика - PullRequest
0 голосов
/ 06 февраля 2019

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

В этом сервисе мы используем3 отдельных HandlerThreads с Handlers для управления различными операциями с некоторой задержкой (например, 250 миллисекунд).Теперь эти действия должны быть остановлены, если экран выключен, и возобновлены, если экран снова включается, из-за этой ситуации мы добавили в службу широковещательный приемник и создали-удалили потоки.Пока все работает нормально.

Чтобы остановить операции, мы удалили сообщения на обработчиках, вызвав Handler.removeCallbacksAndMessages(null), и это фактически очищает очередь сообщений. Однако поток обработчика остается живым. И это проблема.

Чтобы остановить поток, мы использовали HandlerThread.quit(), который внутренне вызывает Looper.quit(), который, как мы думали, будетЗавершить поток, но нет, сэр, он не удаляет поток, потому что мы получаем некоторые отчеты из Fabric, которые отправляются pthread_create failed (1040kb stack), try again или что-то в этом роде.Под ней было 940 отдельных потоков с одинаковыми именами, что вызвало ошибку OOM (Out of Memory). Это была огромная ошибка с нашей стороны.

Вопрос: как мы можемостановить обработчик потоков?Хватит ли HandlerThread.interrupt()?Любая помощь приветствуется, спасибо.PS: я не могу поделиться какими-либо исходными кодами, и в этой ситуации я не думаю, что это необходимо, поскольку сам вопрос не требует пояснений.

Редактировать: Поскольку вы попросили какой-то код, я показываюПример некоторой логики, которой я следую.

public class ThreadHelper implements Runnable
{

    private HandlerThread handlerThread = new HandlerThread("ThreadName");
    private Handler handler;

    private boolean shouldRun = true;

    public ThreadHelper()
    {
        handlerThread.start();
        startThread();
    }

    // Called if the screen state is turned on.
    public void startThread()
    {
        if (handlerThread == null)
        {
             handlerThread = new HandlerThread("ThreadName");
             handlerThread.start();
        }
        if (handler == null)
        {
             handler = new Handler(handlerThread.getLooper());
             handler.post(this);
        }
    }

    // Called if the screen state is turned off.
    public void stopThread()
    {
        shouldRun = false;
        handler.removeCallbacksAndMessages(null);
        handlerThread.quit();
        try
        {
            handlerThread.interrupt();
        }
        catch (Exception ignored)
        {
            // Skipped Thread.currentThread().interrupt() check here since this is
            // called from a different thread that is not associated.
        }

        // remove variables.
        handler = null;
        handlerThread = null;
    }

    @Override
    public void run()
    {
        if (shouldRun)
        {
            // rest of the code without having a long-running
            // operation. Mostly ends in 1~2 millseconds.

            // Continue looping.
            handler.postDelayed(this, 250); 
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...