了java.lang.RuntimeException:唤醒锁定在锁定C2DM_LIB(java.l

2019-06-27 09:57发布

我已经上传我的应用程序在谷歌发挥,但用户报告了以下异常

了java.lang.RuntimeException:唤醒锁定在锁定C2DM_LIB。 当我尝试放开,就会出现此异常WakeLock 。 谁能告诉可能是什么问题。

Answer 1:

我在新的GCM库追溯到相同的异常了。 其实老C2DM的Android库具有同样的错误,死机一样,和谷歌一直未动它。 我可以通过我们的统计看,用户的约0.1%,出现这一崩溃。

我的研究表明,问题是不正确的释放网络WakeLock在GCM库,当库试图释放WakeLock持有什么(内部锁定计数器变为负)。

我很满意简单的解决方案 - 正好赶上这个例外,什么也不做,因为我们不需要做任何额外的工作,然后我们激活锁定抱什么。

为了做到这一点,你需要导入GCM库源在您的项目,而不是已编译.jar文件。 您可以在“$ Android_SDK_Home $ /演员/谷歌/ GCM / GCM的客户端/ src目录 ”文件夹(你需要先下载它使用的是Android SDK管理器)找到GCM库源代码。

接下来打开GCMBaseIntentService类,发现线

sWakeLock.release();

并用的try-catch围绕着它。

它应该是这样的:

    synchronized (LOCK) {
        // sanity check for null as this is a public method
        if (sWakeLock != null) {
            Log.v(TAG, "Releasing wakelock");
            try {
                sWakeLock.release();
            } catch (Throwable th) {
                // ignoring this exception, probably wakeLock was already released
            }
        } else {
            // should never happen during normal workflow
            Log.e(TAG, "Wakelock reference is null");
        }
    }

UPDATE:Alternativally,如建议@fasti 他的回答 ,您可以使用mWakeLock.isHeld()方法来检查是否激活锁定实际持有这个锁。



Answer 2:

你没有发布您的代码,所以我不知道你是否已经做了什么,我会在这里建议,但我也有这样的例外,所有我加入到解决,这是一个简单的“如果”, 以确保激活锁定实际上正在举行,试图将其释放之前

所有我在加的onPause是这样的:“如果”的声明(以下简称“发行()”前):

if (mWakeLock.isHeld())
    mWakeLock.release();

和异常不见了。



Answer 3:

虽然isHeld()解决方案似乎更好,它实际上可以失败 - 因为它不是原子(即不是线程安全的)。 如果你有一个以上的线程可能会释放锁,则检查(isHeld)和RELASE另一个线程可以释放锁的通话之间......然后你失败了。

使用的try / catch你伪装的缺陷,但在一个线程安全的方式。



Answer 4:

我不只要我不重新初始化之后锁,并呼吁在获取新的对象有这个问题。 你应该只保留激活锁定的一个实例(所以使它成为一个字段变量)。 那么你知道你总是释放一个唤醒锁定。

所以....

 if (mWakeLock == null) {
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP
                | PowerManager.ON_AFTER_RELEASE, "MyWakeLock");
    }

try{
        mWakeLock.release();//always release before acquiring for safety just in case
    }
    catch(Exception e){
        //probably already released
        Log.e(TAG, e.getMessage());
    }
    mWakeLock.acquire();


文章来源: java.lang.RuntimeException: WakeLock under-locked C2DM_LIB