2013-09-06 4 views
2

내 생각에 이것은 바보 같은 질문이지만, 여전히 ...android.os.Looper drain battery?

내 앱에서는 (물론 별도의 스레드에서) 순중량 작업을 순서대로 실행해야합니다. 루퍼가 저의 선택이라고 생각합니다. AsyncTask는 그렇지 않습니다. 요청은 언제든지 도착할 수 있고 스레드로부터 안전한 물건은 필요하지 않기 때문입니다.

android.os.Looper 드레인 안드로이드 배터리를 오래 사용합니까?

에서 루퍼의 source code

/** 
* 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(); 
    } 
} 

내가 여기에 우리가 매우 잘 인 부정사 루프를 가지고, 참조하십시오. 그러나 여전히, 나는이 루퍼를 앱의 배경으로 사용하면 모든 활동이 꺼져 있어도 배터리가 아주 빨리 소모된다는 것을 알 수 있습니다.

누구나 알고있는 것은 단지 신화일까요? 아니면 문제 해결을위한 다른 수업을 받아야합니까?

감사합니다.

답변

3

음. 얼마나 많은 메시지와 얼마나 자주이 루퍼에게 보낼지에 달려 있습니다. 무한 루프에서 실행되지만이 구현은 다음 메시지가 계속 진행될 때까지 queue.next()에서 대기합니다. 기다리는 루퍼는 아무것도 소비하지 않습니다. 당신이 끊임없이 많은 메시지를 보내려한다면, 당신은 다른 어떤 것의 루퍼를 사용하든 상관 없습니다. 코드가 실행되고 배터리가 소모됩니다.

+1

http://grepcode.com/file_를 만드는 것입니다 /repository.grepcode.com/java/ext/com.google.android/android/4.3_r2.1/android/os/MessageQueue.java/?v=source .next() 메소드에는 nativePollOnce (...). 다음 메시지가 도착할 때까지 하나의 기본 메소드가 스레드를 차단합니까? – UnknownJoe

+1

예, 스레드를 차단합니다. 나중에 예약 된 메시지 (예 : postDelayed() 메소드로 추가 한 메시지)가 있으면이 지연으로 정의 된 시간 초과로 스레드를 차단합니다. 내 애플 리케이션의 모든 백그라운드 처리 루퍼를 사용하고 그들은 모두 매우 배터리 친화적 인 있습니다. 무엇이든 문제는 안된다.) https://play.google.com/store/apps/details?id=com.hb.settings –

+0

대단히 감사합니다. – UnknownJoe

0

모든 UI 스레드는 루퍼를 가지고 있으므로 그 같은 짐승은 아닙니다 : queue.next(); //이 대부분의 시간 BTW 루퍼와 스레드입니다 HandlerThread를 참조 여기

을 보냈다있다 차단할 수, 당신이해야 할 모든 당신의 노동자 처리기

+0

예, 추가하는 것을 잊었습니다. 내 루퍼는 UI가 아닌 스레드에 바인드됩니다. 대답 해 주셔서 감사합니다. – UnknownJoe

+0

ok, 새 스레드에서 prepare() 및 loop() 메서드를 사용하여 재생할 수 있지만 HandlerThread가 해당 작업을 수행합니다 – pskink