6

在我的应用程序中,在主要活动的 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 待机错误页面,但这是去年发布并关闭的,所以我不知道是不是这样,有人可以帮忙吗?关于最后一点,我也有 HTC Desire,谢谢。

4

3 回答 3

9

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

于 2011-03-29T20:03:23.983 回答
2

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

android:keepScreenOn改为在您的布局中的一个小部件上使用。这对于活动来说比手动处理WakeLock. 另外,您不需要WAKE_LOCK许可,IIRC。

我在 logcat 上的输出在这里

该错误是因为您从未释放WakeLock. 请不要泄漏WakeLocks

现在,您设法编写了所有这些散文并包含所有这些清单,但您忘记了一件小事:实际上告诉我们您的问题是什么。对于像 StackOverflow 这样的问答网站来说,这是一个相当重要的项目。而且,不,“有人可以帮忙吗?” 当您从未定义您希望获得什么“帮助”时,这不算是一个问题。

于 2011-02-19T17:33:26.520 回答
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) {
                }
            }
        }
    }
于 2017-04-06T07:34:27.313 回答