Android - 唤醒锁无法正常获取,应用程序需要继续在待机状态下运行

时间:2011-02-19 17:10:50

标签: android accelerometer standby wakelock android-wake-lock

在我的应用程序中,在主要活动的onCreate()方法中,我正在创建唤醒锁定,以便在手机进入待机/屏幕关闭时CPU将继续运行。

同样在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)

我看到有人说部分唤醒锁没有像他们应该做的那样工作,例如这条链接Google standby error page但是去年已经发布并关闭了所以我不知道是这样的,任何人都可以请帮忙吗?关于最后一点,我也有HTC Desire,谢谢。

3 个答案:

答案 0 :(得分:9)

出现问题是因为您的WakeLock对象是OnCreate方法中的本地范围变量。在执行方法之后 - 不再引用WakeLock对象 - 因此有资格进行垃圾回收。如果Dalvik GC出现 - 对象已准备好进行最终化 - 并且终结器内部代码警告您,WakeLock仍然保持 - 并且处于活动状态 - 但是将进行GC。您必须获取新的WakeLock对象并将其分配给您的活动派生类中的类类型WakeLock的字段。阅读有关面向对象的编程和垃圾收集器 - 您将了解该问题。

答案 1 :(得分:2)

  

在我的应用程序中,在主要活动的onCreate()方法中,我正在创建唤醒锁定,以便在手机进入待机/屏幕关闭时CPU将继续运行。

请在布局中的某个小部件上使用android:keepScreenOn。对于活动而言,这比手动处理WakeLock要安全得多。此外,您不需要WAKE_LOCK权限,IIRC。

  

我在logcat上的输出就在这里

该错误是因为您永远不会释放WakeLock。请不要泄漏WakeLocks

现在,你设法编写所有这些散文并包含所有这些列表,你忘记了一件小事:实际告诉我们你的问题是什么。对于像StackOverflow这样的问答网站来说,这是一个非常重要的项目。而且,不,“请有人帮忙吗?”当你从未定义你想要接受的“帮助”时,这不算是一个问题。

答案 2 :(得分:0)

正如@Michal P所说,你在onCreate方法中获得了一个唤醒锁,但你永远不会释放它。

当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) {
                }
            }
        }
    }