Android.os.Looper разряжает батарею?

Я думаю, это глупый вопрос, но все же...

В моем приложении мне нужно запускать тяжелые задачи последовательно (в отдельном потоке, конечно). Итак, я думаю, что Looper - мой выбор для этого. AsyncTask - не тот случай, потому что запросы могут поступать в любое время, а потокобезопасные вещи не являются необходимыми.

Быстрое ли использование батареи android.os.Looper?

Из исходного кода Looper

/**
 * Run the message queue in this thread. Be sure to call
 * {@link #quit()} to end the loop.
 */
public static void loop() {
    final Looper me = myLooper();
    if (me == null) {
        throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
    }
    final MessageQueue queue = me.mQueue;

    // Make sure the identity of this thread is that of the local process,
    // and keep track of what that identity token actually is.
    Binder.clearCallingIdentity();
    final long ident = Binder.clearCallingIdentity();

    for (;;) {
        Message msg = queue.next(); // might block
        if (msg == null) {
            // No message indicates that the message queue is quitting.
            return;
        }

        // This must be in a local variable, in case a UI event sets the logger
        Printer logging = me.mLogging;
        if (logging != null) {
            logging.println(">>>>> Dispatching to " + msg.target + " " +
                    msg.callback + ": " + msg.what);
        }

        msg.target.dispatchMessage(msg);

        if (logging != null) {
            logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
        }

        // Make sure that during the course of dispatching the
        // identity of the thread wasn't corrupted.
        final long newIdent = Binder.clearCallingIdentity();
        if (ident != newIdent) {
            Log.wtf(TAG, "Thread identity changed from 0x"
                    + Long.toHexString(ident) + " to 0x"
                    + Long.toHexString(newIdent) + " while dispatching to "
                    + msg.target.getClass().getName() + " "
                    + msg.callback + " what=" + msg.what);
        }

        msg.recycle();
    }
}

Я вижу, что здесь у нас есть бесконечный цикл, что вполне нормально. Но, тем не менее, я боюсь, что наличие этого Looper на заднем плане приложения будет довольно быстро разряжать батарею, этот цикл будет работать, даже когда все действия отключены.

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

Спасибо за ваше время.

2 ответа

Решение

Что ж. Это зависит от того, сколько сообщений и как часто вы будете отправлять этому петлителю. Хотя он работает в бесконечном цикле, эта реализация будет ждать в queue.next() для следующего сообщения, чтобы продолжить. В ожидании петлитель ничего не потребляет. Если вы собираетесь отправлять много сообщений постоянно, то не имеет значения, используете ли вы петлитель чего-либо еще. Ваш код будет работать и будет расходовать заряд батареи.

У каждого потока пользовательского интерфейса есть Looper, так что это не такой зверь, смотрите: queue.next(); // может блокировать, большая часть времени проводится здесь

Кстати, смотрите HandlerThread, который является потоком с Looper, все что вам нужно сделать, это создать ваш рабочий обработчик

Другие вопросы по тегам