2011-08-25 1 views
1

문제WakeLock 관련 Mandelbug : WakeLock.acquire()가 항상 성공합니까?

저는 오랫동안 Android 용으로 개발해 왔습니다. 내가 개발 한 프로그램 중 하나가 WakeLocks을 많이 사용합니다. hasWakeLock() 단순히 (wakeLock != null && wakeLock.isHeld())wakeLockManager.newPartialWakeLock(DEBUG_TAG)의 결과를 반환

acquireWakeLock(wakeLockManager) 

    // Preconditions 
    assertFalse("Wake lock already acquired.", hasWakeLock()); 
    assertNotNull("Wake lock manager not provided.", wakeLockManager); 

    // Acquire a wake lock. 
    wakeLock = wakeLockManager.newPartialWakeLock(DEBUG_TAG); 
    wakeLock.acquire(); 

    // Postconditions 
    assertTrue("Wake Lock should be held!", hasWakeLock()); 

가 캡슐화 : 그것은 일반적으로 완벽하게 (종종 시간, 프로그램의 요구 사항에 일 주간), 그러나 매우 드물게이 코드에서 특이한 동작을 확인할 수 없습니다 표준 "PowerManager 가져 오기 후 깨우기 잠금"코드를 반환하십시오. 테스트의 목적을 위해 assert 문은 JUnit assert 메서드이므로 올바른 것으로 가정 할 수 있습니다.

코드의 문제점은 다음과 같습니다. 최종 어설 션 - assertTrue(hasWakeLock()) - 거의 설명하지 않고 몇 주마다 실패한 것으로 보입니다. 여기에 세 가지 문제가 있습니다 : (1) 동시성 문제가있는 PowerManager (2)에서 절전 모드 잠금이 전혀 검색되지 않습니다. 드문 경우이지만 사후 조건 바로 전에 적용되지만 acquire() 호출 후, 또는 (3) acquire()가 때때로 결함이 있습니다. 의

조사 문제

위에서 언급 한 바와 같이, 내가 조사한/I가 조사하고 있다고이 발생 될 수 있습니다 세 가지 잠재적 인 문제를 가지고 :

가설 1 : 시동이 반환되지 자물쇠

이 경우 null 포인터 예외가 표시됩니다. 그것은 그럴 수 없다.

가설 2 : 획득하고 wakeLock 방출에 관련된 모든 장소의

정당한-실시 형식 검증 증거가 강력하게 이러한 경우가 믿고 날 리드 : 나는 동시성 문제 있습니다. 내 증거가 잘못되어있는 경우 동시성 문제가있을 수 있지만 정말 교활하고 찾기가 어렵습니다.

가설 3 : WakeLock.acquire은()에 결함이, 그리고 despite what the documentation says은 때로는 잠금 획득 실패 할 수에서 우리가 사람 옆 때문에 안드로이드 사용자 모두와 함께

나는이 가설을 싫어하는을 나는 지금 당장이 사실을 알아 차렸을 것입니다. 그리고 그것은 거의 항상 개발자의 코드이지 라이브러리 나 OS 코드가 아닙니다. 그런데 다시 낯선 것들이 생겼고 이것은 드물게 전시 된 것이지만 진정한 안드로이드 버그 일 수 있습니다. 이 가설이 참이라면 acquire()는 단순히 잠김 잠금을 얻지 못하고 있으며 이는 내가 보는 행동을 설명 할 것입니다.

그래서 StackOverflow,이 문제의 원인은 무엇입니까? 뭐가 잘못됐다고 생각하니? 명백한 무언가를 놓치고 있습니까? 아니면 Android의 잠자기 잠금 기능에있어서 이것이 진정한 문제 일 수 있습니까?

+1

다른 공급 업체의 장치에서이 버그가 표시됩니까? 아니면 에뮬레이터에서도이 문제를 재현 할 수 있을까요? – inazaruk

+0

Google IO 기기에서만 사용 가능합니다. Android 2.1의 맞춤 버전을 실행 중입니다. 사용자 정의 버전은 Bluetooth 코드 만 수정합니다. –

+1

이 버그를 설명하는 것이 드문 경우, 내 첫 번째 방법은 다른 공급 업체의 장치 또는 Android 2.2가 설치된 동일한 장치에서 다시 작성하는 것입니다. – inazaruk

답변

0

실제로 이것은 동시성 문제였던 것으로 보입니다. 관련 메소드가 별도의 스레드에서 동기화되지 않은 위치에서 호출 될 수 있다는 사실을 간과했습니다. 이는 매우 다중 스레드 환경에서 명백한 문제입니다!