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

Posted

技术标签:

【中文标题】在 onPostExecute 中的 notify() 之前没有被线程锁定的对象【英文标题】:Object not locked by thread before notify() in onPostExecute 【发布时间】:2014-08-02 20:50:05 【问题描述】:

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

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

【问题讨论】:

你确定这个异常是由这段代码引起的吗? 【参考方案1】:

.notify() 方法必须从 synchronized 上下文中调用,即从 synchronized 块内调用。

java.lang.IllegalMonitorStateException 是在您调用 .notify() 时引发的,该对象未用作您调用 notify 的同步块的锁。例如,以下作品;

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();        

参考;

IllegalMonitorStateException API How to use wait & notify

【讨论】:

【参考方案2】:

我遇到了同样的错误,但(对我而言)Rudi Kershaw 建议的答案不是问题...我以错误的方式调用了通知的notify()(请参阅最后一行 em> 的两个 sn-ps):

不工作:

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 的声明位置请告诉我 Const 在我的项目中包含常量值。按 Ctrl+P(将光标设置在“通知”上并按下快捷方式)查看参数信息 -> 它是一个整数(类似于您必须提供通知的 ID)。您还可以添加一个名为“Const”的新类,只需在光标位于 Const 上时按 Alt+Enter 并选择创建“新类”。 ;) 知道了? 注意: 如果您有多个通知,它们需要有不同的 ID。要清除通知,您也将使用此 ID。

以上是关于在 onPostExecute 中的 notify() 之前没有被线程锁定的对象的主要内容,如果未能解决你的问题,请参考以下文章

片段中的 Asynctask 未到达 onPostExecute

在检查空值时 onPostExecute 中的 AsyncTask 中的空指针异常

无法在 asyncTask 中的 onPostExecute 中发送消息

无法覆盖 AsyncTask 类中的 onPostExecute() 方法或使其触发

onPostExecute 中的空指针异常

在异步任务中更改 onPostexecute 中的可见性设置