【问题标题】:Java thread goes to sleep when not in focus on OSXJava 线程在不关注 OSX 时进入睡眠状态
【发布时间】:2012-04-24 04:21:14
【问题描述】:

我正在编写一个程序来监听系统剪贴板的变化。侦听器在单独的线程上运行,并在剪贴板的内容发生更改时执行一些操作(例如,写入文件)。

我正在使用ClipboardOwner interface 轮询剪贴板,因此当我的程序失去剪贴板的所有权(意味着另一个进程已修改剪贴板)时,我的程序中会触发一个事件,让我读取更改。

public class OwnershipClipboardListener extends Thread implements ClipboardOwner
{
    private Clipboard clipB = Toolkit.getDefaultToolkit().getSystemClipboard();

    public void run()
    {
        /* Initialize ClipboardListener and gain ownership of clipboard */
    }

    @Override
    public void lostOwnership(Clipboard clipboard, Transferable transferable)
    {
        /* Auto-fired when I lose Clipboard ownership.
           Can do processing and regaining ownership here */
    }    
}

问题是,在 OSX 中运行时,只有当我手动 Cmd-Tab 到停靠栏中正在运行的进程图标时,才会反映对剪贴板的任何更改。所以如果在我切换到停靠图标之前有多个剪贴板操作,只有最后一个有任何影响。我在 Linux 或 Windows 上没有遇到这个问题。

就像程序失去焦点时线程进入睡眠状态,但最后一个事件触发器在唤醒时仍然触发。有什么办法可以防止这种睡眠吗?

【问题讨论】:

  • 帖子thisthis 似乎有类似的问题,但在大多数情况下,他们的剪贴板是进行一些数据传输的一种解决方法。我实际上需要一直阅读剪贴板。

标签: java multithreading macos clipboard


【解决方案1】:

我怀疑 OSX 不提供剪贴板更改通知,因此 Java 尽其所能通过在因其他原因被唤醒时通知您。

我的怀疑来自NSPasteboard 文档,尤其是changeCount 例程。它说“因此,您可以在获得粘贴板所有权时记录更改计数,然后将其与从 changeCount 返回的值进行比较,以确定您是否仍然拥有所有权。”没有提到使用事件来检测变化。

【讨论】:

  • 但在这种情况下,lostOwnership() 方法确实被触发了,只是它仅在我将焦点切换到 Java 应用程序时才会发生。在其他系统上,即使在后台也会触发该事件。
  • 我的意思是操作系统不会通知 JVM 发生了变化。 JVM 显然会为您检查 changeCount,但只有当它获得一些周期时,例如当它的一个窗口获得焦点时。
【解决方案2】:

看来基思是对的。但是,您可以通过将应用程序发送到后台(在 *Nix 上)来解决问题:

java -jar clipboard-1.0.jar &

这会在后台打开 Java 应用程序,并且不需要窗口焦点来触发通知。

【讨论】:

    猜你喜欢
    • 2012-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-12
    • 1970-01-01
    相关资源
    最近更新 更多