2011-02-19 85 views
6

在我的應用中,在主要活動的onCreate()方法中,我創建了一個喚醒鎖,以便在手機繼續運行時CPU將繼續運行Standb /屏幕關閉。Android - 喚醒鎖無法正常獲取,應用需要保持正常運行

另外在onCreate方法中,我有意創建一個使用加速計的服務。這項服務需要持續運行,而應用程序是開放的,並監測加速度計值(我知道這不適合電池,但我需要它做到這一點)。這是我目前的代碼,服務啓動正常。

public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE); 
     PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Howaya"); 
     wl.acquire(); 

     if (appStart == true) 
     { 
      Intent AccelService = new Intent(this, Accelerometer.class); 
      AccelService.putExtra("unreg", false); 
      startService(AccelService); 
     } 
     appStart = false; 
    } 

我有以下權限在我的清單設置 -

<uses-permission android:name="android.permission.WAKE_LOCK" /> 

我有不同的鎖嘗試這個 - 昏暗的屏幕和全亮度無濟於事了。我在logcat的輸出是在這裏 -

F/PowerManager(15628): android.util.Log$TerribleFailure: WakeLock finalized while still held: Howaya 
F/PowerManager(15628): at android.util.Log.wtf(Log.java:260) 
F/PowerManager(15628): at android.util.Log.wtf(Log.java:239) 
F/PowerManager(15628): at android.os.PowerManager$WakeLock.finalize(PowerManager.java:329) 
F/PowerManager(15628): at dalvik.system.NativeStart.run(Native Method) 

我看到有人說,部分wakelocks不工作像他們應該做的,比如這個鏈接Google standby error page但被釋放,去年關閉的,所以我不知道是這樣的話,任何人都可以在這裏幫忙嗎?關於最後一點,我也有HTC Desire,謝謝。

回答

2

在我的應用程序中,在主要活動的onCreate()方法中,我創建了一個喚醒鎖,以便CPU在手機進入standb/screen時關閉。

請在您的佈局中的其中一個小部件上使用android:keepScreenOn。這遠比手動處理WakeLock更安全。另外,你不需要WAKE_LOCK許可,然後,IIRC。

我在logcat的輸出是在這裏

該錯誤是因爲你永遠不放開WakeLock。請不要泄漏WakeLocks。現在

,你設法寫這段散文,包括所有這些物品的,你忘了一個小東西:實際上告訴我們,你的問題是什麼。對於像StackOverflow這樣的問答網站來說,這是一個相當重要的項目。而且,不,「有人可以幫忙嗎?」當你永遠不會定義你希望得到的「幫助」時,這不算是一個問題。

+0

好的抱歉,如果我不清楚,並感謝您的答覆。我的問題是我怎樣才能在手機上運行wakelock,以便我的應用在屏幕仍然關閉時運行,因爲我上面使用的代碼不起作用。我寧願不打開屏幕,這樣它就不會浪費太多電量,也不必使用這個小部件,以防我決定將其投放市場(其他用戶將不得不使用該部件) – bobby123

+1

@ bobby123 :一個活動無法滿足部分'WakeLock'的邏輯需要。一個* service *可能需要一個局部'WakeLock',而不是一個活動,它的唯一目的是在屏幕上顯示東西。因此,要麼將WakeLock從活動中移出並放入服務中(調整業務邏輯以匹配),要麼使用'android:keepScreenOn'。在你的服務的onCreate()中獲取你的'WakeLock',並在'onDestroy()'中釋放它。使用'startForeground()',這樣你的服務就不會被破壞,並且讓用戶可以輕鬆地到達一個活動來停止服務。 – CommonsWare

+0

這就是我想知道的,謝謝。我會將喚醒鎖移動到服務中,因爲這正是我真正需要的。我有一個菜單按鈕供用戶隨時結束服務。最後一個問題請問,你知道加速度計的onSensorChanged()方法在部分喚醒鎖定下仍然可以工作嗎?或者這仍然是Google的問題嗎? – bobby123

9

問題發生是因爲您的WakeLock對象是OnCreate方法內的本地作用域變量。在執行方法之後 - WakeLock對象不再被引用 - 因此符合垃圾回收的條件。如果Dalvik GC發生 - 對象已準備好進行最終確定 - 並且終結器內部代碼警告您,那個WakeLock仍然處於活動狀態 - 但會被GC化。您必須獲取新的WakeLock對象,並將其分配給活動派生類中類類型WakeLock的字段。閱讀關於面向對象的編程和垃圾收集器 - 你會理解這個問題。

0

由於@Michal P說,你在onCreate方法中獲得了一個wakelock,但是你永遠不會釋放它。

當GC掃描這個零引用的對象時,調用默認的finalize方法,但實際上它是活動的。

@Override 
    protected void finalize() throws Throwable { 
     synchronized (mToken) { 
      if (mHeld) { 
       Log.wtf(TAG, "WakeLock finalized while still held: " + mTag); 
       Trace.asyncTraceEnd(Trace.TRACE_TAG_POWER, mTraceName, 0); 
       try { 
        mService.releaseWakeLock(mToken, 0); 
       } catch (RemoteException e) { 
       } 
      } 
     } 
    }