Android 我的应用程序因为wakelock而崩溃;“不要睡觉”;

Android 我的应用程序因为wakelock而崩溃;“不要睡觉”;,android,Android,我的应用程序可以工作,但当它停止服务时,它只是崩溃了,因为wakelock处于“DoNotSleep”状态,所以我很高兴听到一些建议。 这是我的日志: 05-15 00:41:06.925: E/AndroidRuntime(4471): FATAL EXCEPTION: main 05-15 00:41:06.925: E/AndroidRuntime(4471): java.lang.RuntimeException: Unable to stop service com.example.

我的应用程序可以工作,但当它停止服务时,它只是崩溃了,因为wakelock处于“DoNotSleep”状态,所以我很高兴听到一些建议。 这是我的日志:

05-15 00:41:06.925: E/AndroidRuntime(4471): FATAL EXCEPTION: main

05-15 00:41:06.925: E/AndroidRuntime(4471): java.lang.RuntimeException: Unable to stop service com.example.iw84u.GpsTracker@40812c40: java.lang.RuntimeException: WakeLock under-locked DoNotSleep

05-15 00:41:06.925: E/AndroidRuntime(4471):     at android.app.ActivityThread.handleStopService(ActivityThread.java:2086)

05-15 00:41:06.925: E/AndroidRuntime(4471):     at android.app.ActivityThread.access$2900(ActivityThread.java:117)

05-15 00:41:06.925: E/AndroidRuntime(4471):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1001)

05-15 00:41:06.925: E/AndroidRuntime(4471):     at android.os.Handler.dispatchMessage(Handler.java:99)

05-15 00:41:06.925: E/AndroidRuntime(4471):     at android.os.Looper.loop(Looper.java:130)

05-15 00:41:06.925: E/AndroidRuntime(4471):     at android.app.ActivityThread.main(ActivityThread.java:3691)

05-15 00:41:06.925: E/AndroidRuntime(4471):     at java.lang.reflect.Method.invokeNative(Native Method)

05-15 00:41:06.925: E/AndroidRuntime(4471):     at java.lang.reflect.Method.invoke(Method.java:507)

05-15 00:41:06.925: E/AndroidRuntime(4471):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:907)

05-15 00:41:06.925: E/AndroidRuntime(4471):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665)

05-15 00:41:06.925: E/AndroidRuntime(4471):     at dalvik.system.NativeStart.main(Native Method)

05-15 00:41:06.925: E/AndroidRuntime(4471): Caused by: java.lang.RuntimeException: WakeLock under-locked DoNotSleep

05-15 00:41:06.925: E/AndroidRuntime(4471):     at android.os.PowerManager$WakeLock.release(PowerManager.java:311)

05-15 00:41:06.925: E/AndroidRuntime(4471):     at android.os.PowerManager$WakeLock.release(PowerManager.java:286)

05-15 00:41:06.925: E/AndroidRuntime(4471):     at com.example.iw84u.GpsTracker.onDestroy(GpsTracker.java:126)

05-15 00:41:06.925: E/AndroidRuntime(4471):     at android.app.ActivityThread.handleStopService(ActivityThread.java:2069)
05-15 00:41:06.925: E/AndroidRuntime(4471):     ... 10 more
在我的代码中,服务wakelock中存在:

public void onCreate() {
        super.onCreate();
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DoNotSleep");
}
public void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();

     wakeLock.release();

    }
public int onStartCommand(Intent intent, int flags, int startId) {
    // Here there's some calculations with the intent

        return START_REDELIVER_INTENT;

    }
private void UpdateWithNewLocation(final Location loc) {
//Some commands and then .....
 stopSelf(); 
}

我该怎么处理wakelock的崩溃?谢谢。

在释放Wakelock之前,您必须先获取它

public void onCreate() {
    super.onCreate();
    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DoNotSleep");

    // ADD THIS LINE
    wakeLock.acquire();
}

在释放Wakelock之前,必须先获取它

public void onCreate() {
    super.onCreate();
    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DoNotSleep");

    // ADD THIS LINE
    wakeLock.acquire();
}

您需要先获取唤醒锁,然后才能释放它:

这是因为唤醒锁在默认情况下是引用计数的。如果对唤醒锁进行了引用计数,则每次对acquire()的调用必须与对release()的调用数量相等(反之亦然)。如果一个唤醒锁是引用计数的,并且您释放它的频率高于获取它的频率(在您的情况下,您根本没有获取它),那么将抛出锁定异常下的唤醒锁

您的代码只创建了一个唤醒锁,但它从未获得它。为了平衡计数,请在onCreate()中获取它:


您需要先获取唤醒锁,然后才能释放它:

这是因为唤醒锁在默认情况下是引用计数的。如果对唤醒锁进行了引用计数,则每次对acquire()的调用必须与对release()的调用数量相等(反之亦然)。如果一个唤醒锁是引用计数的,并且您释放它的频率高于获取它的频率(在您的情况下,您根本没有获取它),那么将抛出锁定异常下的唤醒锁

您的代码只创建了一个唤醒锁,但它从未获得它。为了平衡计数,请在onCreate()中获取它:


您需要调用
wakeLock.release()
before
super.ondestory()@Onur这肯定是错误的建议,不会改变一个错误thing@Emanuel嗯,这至少是个好习惯<代码>super.ondestory()显然会破坏服务,因此必须最后调用它。就像在重写onCreate时,首先调用super。对于真正的答案,我没有意识到他没有调用wakeLock.acquire()。如果(wakeLock.ishelld()){wakeLock.release();}应该这样做。@EmanuelMoecklin:虽然“需要”可能说得太多了,但我绝对建议您在
super.onDestroy()之前进行自己的清理。
。这样,如果您自己的清理依赖于受
super.ondestory()
影响的内容,那么您仍然是安全的。实际上,这不太可能是一个问题(在别人指出我的错误之前,我通常先调用
super.ondestory()
),但这仍然是一个好主意。@Onur可能是一个好做法,但“必须最后调用”是不正确的。而且super.onCreate也不必先调用。文档很清楚:“派生类必须调用该方法的超类实现。如果不调用,将引发异常”。必须通过调用并不意味着它必须是第一个调用(它不是构造函数!),即使通常是这样
before
super.ondestory()@Onur这肯定是错误的建议,不会改变一个错误thing@Emanuel嗯,这至少是个好习惯<代码>super.ondestory()显然会破坏服务,因此必须最后调用它。就像在重写onCreate时,首先调用super。对于真正的答案,我没有意识到他没有调用wakeLock.acquire()。如果(wakeLock.ishelld()){wakeLock.release();}应该这样做。@EmanuelMoecklin:虽然“需要”可能说得太多了,但我绝对建议您在
super.onDestroy()之前进行自己的清理。
。这样,如果您自己的清理依赖于受
super.ondestory()
影响的内容,那么您仍然是安全的。实际上,这不太可能是一个问题(在别人指出我的错误之前,我通常先调用
super.ondestory()
),但这仍然是一个好主意。@Onur可能是一个好做法,但“必须最后调用”是不正确的。而且super.onCreate也不必先调用。文档很清楚:“派生类必须调用该方法的超类实现。如果不调用,将引发异常”。必须通过调用并不意味着它必须是第一个调用(它不是构造函数!),即使它通常是。我现在没有看到错误,但我的服务没有停止+请看这里:你已经得到了答案。我建议将获取/发布放在onstart命令的开头和结尾。这是你做所有处理和设备需要唤醒的地方。我现在没有看到错误,但我的服务没有停止+请看这里:你已经得到了答案。我建议将获取/发布放在onstart命令的开头和结尾。这就是你进行所有处理的地方,也是设备需要唤醒的地方。正如我在其他评论中所说,它确实停止了appstoped的错误。。但实际上服务并没有停止。。。仅当我移除wakeLock.acquire()时;它停止了。正如我在其他评论中所说,它确实停止了appstoped的错误。。但实际上服务并没有停止。。。仅当我移除wakeLock.acquire()时;到此为止。