Android 我的应用程序因为wakelock而崩溃;“不要睡觉”;
我的应用程序可以工作,但当它停止服务时,它只是崩溃了,因为wakelock处于“DoNotSleep”状态,所以我很高兴听到一些建议。 这是我的日志: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.
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()
beforesuper.ondestory()代码>@Onur这肯定是错误的建议,不会改变一个错误thing@Emanuel嗯,这至少是个好习惯<代码>super.ondestory()代码>显然会破坏服务,因此必须最后调用它。就像在重写onCreate时,首先调用super。对于真正的答案,我没有意识到他没有调用wakeLock.acquire()代码>。如果(wakeLock.ishelld()){wakeLock.release();}应该这样做。@EmanuelMoecklin:虽然“需要”可能说得太多了,但我绝对建议您在super.onDestroy()之前进行自己的清理。
。这样,如果您自己的清理依赖于受super.ondestory()
影响的内容,那么您仍然是安全的。实际上,这不太可能是一个问题(在别人指出我的错误之前,我通常先调用super.ondestory()
),但这仍然是一个好主意。@Onur可能是一个好做法,但“必须最后调用”是不正确的。而且super.onCreate也不必先调用。文档很清楚:“派生类必须调用该方法的超类实现。如果不调用,将引发异常”。必须通过调用并不意味着它必须是第一个调用(它不是构造函数!),即使通常是这样
beforesuper.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()时;到此为止。