在onPostExecute中的notify()之前,对象未被线程锁定

49

我试图在onPostExecute中通知主类的列表视图适配器,但是我收到了错误消息:java.lang.IllegalMonitorStateException:object not locked by thread before notify()

@Override
protected void onPostExecute(String result) {
    popularfragment.adapter.notifyDataSetChanged();
    recentfragment.adapter.notifyDataSetChanged();
} 

2
你确定这个异常是由这段代码引起的吗? - Marco Acierno
2个回答

98
.notify() 方法必须在一个 synchronized 代码块中调用,也就是说,必须在一个 synchronized 块内部调用。

当你在一个不是被用作同步块锁的对象上调用.notify()方法时,会抛出java.lang.IllegalMonitorStateException异常。例如,以下代码可以正常工作;

synchronized(obj){
    obj.notify();
}

但是这将抛出异常;

synchronized(obj){
    // notify() is being called here when the thread and 
    // synchronized block does not own the lock on the object.
    anotherObj.notify();        
}

参考资料;


3

我曾经遇到同样的错误,但是(对我而言)Rudi Kershaw建议的答案并不是问题所在... 我错误地调用了通知的notify()方法(请查看两个片段的最后一行):

无法工作:

public void update() {
    mBuilder.setSmallIcon(R.drawable.ic_launcher)
            .setPriority(AesPrefs.getInt(R.string.PRIORITY_NOTIFICATION_BATTERY, NotificationCompat.PRIORITY_MAX))
            .setOngoing(true);
    mBuilder.setWhen(AesPrefs.getLong(Loader.gStr(R.string.LAST_FIRED_BATTERY_NOTIFICATION) + Const.START_CLIPBOARD_NOTIFICATION_DELAYED, -1));
    mManager.notify(); // <- lil' mistake
}

工作中:

public void update() {
    mBuilder.setSmallIcon(R.drawable.ic_launcher)
            .setPriority(AesPrefs.getInt(R.string.PRIORITY_NOTIFICATION_BATTERY, NotificationCompat.PRIORITY_MAX))
            .setOngoing(true);
    mBuilder.setWhen(AesPrefs.getLong(Loader.gStr(R.string.LAST_FIRED_BATTERY_NOTIFICATION) + Const.START_CLIPBOARD_NOTIFICATION_DELAYED, -1));
    mManager.notify(Const.NOTIFICATION_CLIPBOARD, mBuilder.build()); // <- ok ;-)
}

嘿,我使用了你的代码,但是我不知道Const在哪里声明,请告诉我。 - Mahdi Javaheri
在我的项目中,Const 包含常量值。按 Ctrl+P(将光标置于“notifiy”上并按快捷键)以查看参数信息->它是一个整数(类似于您必须为通知提供的 ID)。 您还可以添加一个名为“Const”的新类,只需在光标位于 Const 上时按 Alt+Enter 并选择创建“新类”。;)明白了吗? 注意:如果您有多个通知,则它们需要具有不同的 ID。要清除通知,您也将使用此 ID。 - Martin Pfeffer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接