工作线程无法更新 Motorola V3 上的 UI

Posted

技术标签:

【中文标题】工作线程无法更新 Motorola V3 上的 UI【英文标题】:Worker thread unable to update the UI on Motorola V3 【发布时间】:2011-01-24 23:15:43 【问题描述】:

我正在开发一个应该移植到不同供应商手机的 J2ME 应用程序。到目前为止,该应用程序运行良好,除了在摩托罗拉 V3 上(这是我尝试过的唯一一部摩托罗拉手机)。

问题是当我启动一个新线程时,当线程尝试更新图形时(通过调用 repaint()),图形系统是堆栈的。

一些有用的信息: - 我在 Midlet 的构造函数中获取显示,并在应用程序生命周期内重用它。 - 只有一个类扩展 Canvas。每幅画都在这里发生。当我想要重新绘制图形时,我会从 UI 线程或另一个 Worker 线程调用 repaint() 方法。据我所知,每个线程都可以毫无问题地访问 UI。 - 我尝试了一个修复,在应用程序的开头,我获取正在运行的(UI)线程的名称并将其存储以供以后使用。在调用 repaint() 之前,我检查当前线程的名称是否等于 UI 线程的名称。如果它是颂歌,那么我做repaint(),否则我做:

display.callSerially(new Runnable() 
    public void run() 
        repaint();
    
);

您能否指出摩托罗拉实施 J2ME 的任何细节?如何通过线程更新 UI 来解决这个问题?

谢谢, 兹拉特科

【问题讨论】:

【参考方案1】:

与 Swing 不同,MIDP 用户界面 API 是线程安全的。这意味着您不必使用 callSerially 来强制在 UI 线程上运行。有报道称 callSerially 在某些摩托罗拉设备上不能很好地工作,所以最好的办法是自己调用 repaint。

请注意,重绘只是对系统进行重绘的建议。如果你想强制重绘立即发生,你必须调用 serviceRepaints 方法。

可以找到关于 MIDP UI 事件处理的很好的讨论 here。

【讨论】:

感谢您的回复。我最初的方法是按照您的建议直接从工作线程更新 UI,同时牢记您提到的规范。它不起作用。这就是促使我寻找其他解决方案的原因(包括我在帖子中写的那个)。 为了让我的用例更清晰:在应用启动时显示了一张图像,用于启动画面。在那一刻,我生成了一个等待 5 秒的新线程,然后更改应该由 paint() 方法使用的图像并调用 repaint()。但是,第二张图片从未出现,但第一张(飞溅)却出现了。似乎 repaint() 没有第二次执行或阻塞(此代码在许多其他设备上完美运行)。有什么想法吗? 可能是事件线程被阻塞了。你能给我们看看代码吗? 请查看以下 URL 以获取格式化和语法颜色的代码:copypastecode.com/62605 这是代码的改编版本,以显示概念,尽管实际代码更复杂。如果有什么不清楚的地方,我很乐意解释。 现在我不明白你为什么要创建 CanvasManager 类。这就像你试图自己管理屏幕而不是让系统来做。我会摆脱那些东西,只使用普通的 Display 方法来推送和弹出屏幕。对于初始屏幕,使用 Canvas 但在 showNotify() 方法中启动计时器线程。然后,计时器线程只需在时间到期时将显示设置为适当的屏幕。

以上是关于工作线程无法更新 Motorola V3 上的 UI的主要内容,如果未能解决你的问题,请参考以下文章

MailChimp API v3 - 无法修补/更新?

D3 树图 v3 到 v4

在后台更新低准确度的地理围栏,以高精度更新地图上的位置,无法按预期工作

无法检测到 CCNode 上的触摸 - cocos2d v3.0

Android上的启动画面无法正常工作

Windows 10 上的 RabbitMQ - 无法连接到 epmd:地址(无法连接到主机/端口)