2013-09-01 13 views
1

최근 응용 프로그램의 전원 관리 섹션을 다시 작성하여 복잡성을 줄였습니다. 변화 중에는 wakelocks의 재사용이있었습니다. 특히 스레드는 생성시 wakelock을 수신 한 다음 필요에 따라 스레드를 제거 할 때까지 획득/해제합니다. 나는이 결과가 release()이 호출 될 때 항상 해제되지 않는 wakelocks를 발견했다. 그 본질에서 문제가 발생 코드는 여기에 주어진 :WakeLock이 항상 출시되는 것은 아닙니다

  1. 은 다른 사람이이 발생했습니다 : 당신에

    // Get the lock for the first time, acquire it, and do some work. 
    WakeLock wakelock = receiveFirstWakeLock(); 
    wakelock.acquire(); 
    doWork(); 
    
    // When work is finished, release the lock. 
    // Typically this lock is released very quickly. 
    wakelock.release(); 
    
    // Re-acquiring the lock for the next bout of work always works. 
    wakelock.acquire(); 
    doWork(); 
    
    // In my full code, "wakelock" didn't appear to be releasing properly. 
    // I hypothesized that it might just be taking a little while 
    // so I tried this to see how long it would take. 
    // I found that it sometimes *never* releases! 
    wakelock.release(); 
    while (wakelock.isHeld()) 
        Thread.yield(); 
    Log.d("Test","Released the lock!"); 
    

    내 질문?

  2. 이러한 방식으로 wakelock을 다시 사용할 수 있습니까?
  3. 예 # 2 인 경우 버그입니까?
  4. # 2에 없다면 문서의 어딘가에 이것을 놓쳤습니까?
+0

두 번째 doWork()가 차단되어 릴리스를 실행하지 못하도록 하시겠습니까? Wakelock에 어떤 플래그를 사용하고 있습니까? – Julien

+0

분명히 차단하지 않습니다. 심지어 전체 코드에서 훨씬 더 복잡합니다 (작업 루프 임). 두 번째 wakelock.release()는 항상 도달합니다. 때로는 풀리지도 않으나, 처음 도달 할 때 항상 풀리는 것처럼 보입니다. PARTIAL_WAKE_LOCK을 (를) 사용하고 있습니다. –

답변

4

나는 무슨 일이 일어 났는지 알았습니다. WakeLock 설명서에 따르면 기본적으로 wakelocks는 acquire()release()의 균형 전화를 요구합니다. 이러한 일이 발생하지 않으면 release()은 실제로 잠금을 해제하지 않습니다. 내 코드에는 마이크로 슬리핑 (microsleeping) 목적으로 동일한 wakelock을 사용하는 중첩 된 작업이 있습니다. 체인 중 하나 이상을 제어하기 전에 해제하는 것보다 한 번 더 wakelock을 가져 오는 경우 (예 : 부적절하게 처리 된 인터럽트가 발생하는 경우) 잠금이 해제되지 않습니다. 나는 setReferenceCounted()WakeLock.toString()을 조사하여 후자가 acquire()이 얼마나 많은 시간 동안 밸런싱없이 호출되었는지를 알려줍니다. release(). 바라기를 이것은 유사한 문제를 경험하는 누군가를 돕는다!