如何在 Android 中高效地与 UI 线程通信?

Posted

技术标签:

【中文标题】如何在 Android 中高效地与 UI 线程通信?【英文标题】:How to communicate with UI thread efficiently in Android? 【发布时间】:2017-10-21 19:23:20 【问题描述】:

我不擅长 android 技术,这就是我发布问题的原因。

远程服务器通过 TCP 连接以高频率(高达 30 fps)将图片发送到 Android 设备。 Android 设备是获取图片并显示在 ImageView 容器中(模拟视频)。

因为 UI 操作只允许从主线程进行,所以我遇到了一些性能问题。现在网络接收操作在单个线程中运行,它根据docs 将每个接收到的图片上的数据移动到 UI 线程。

我有两个想法可以提高性能:

    跳过一些图片(UI 线程自行更新并从与网络线程共享的某些资源中获取最新帧) 以某种方式优化绘图过程(现在我只是将位图分配给 ImageView)

由于 Android 体验不佳,我无法确定这些想法是否受到赞赏。所以欢迎任何建议。 谢谢。

【问题讨论】:

也许第二个线程从 ConcurrentLinkedQueue 或任何其他线程安全队列中读取数据并将轮询的图像发布到您的视图中? @JacksOnF1re 这可能是个好主意(我正在考虑自己实现线程安全队列),我将测试它的性能。但我认为真正的里程碑是在屏幕上绘制图像(现在我从原始 jpeg/png/bmp 数据构建位图并将其分配给 ImageView)。 如果您可以控制服务器,我会通过 UDP 将其作为视频流式传输。 @nasch 虽然 UDP 更适合实时流量,但我使用 TCP(因为我使用的消息传递框架不支持 UDP)。 【参考方案1】:

我可能是错的,但我看不出多线程如何为您带来更好(有用的)性能。我建议您减少图像或编码(在源中),然后还原 - 解码(在接收器上)。一个地方可以去:https://developer.android.com/topic/performance/network-xfer.html

但是你必须问自己关于图像、尺寸的问题,如果你有一张大图,你真的需要它吗?你没有谈论它,它在大多数情况下很重要。像大小这样的参数很重要。如果这对您来说是一个不错的选择,这篇文章可以帮助您:https://developer.android.com/topic/performance/graphics/load-bitmap.html

【讨论】:

确定图像在服务器上编码,而不是在接收器上解码。而且我意识到图像大小很重要,但是 LAN 连接允许传输足够的数据以达到 30+ fps,而 UI 不能显示超过 12-15 fps。需要多线程,只是因为无法在主(UI)线程中建立网络连接。

以上是关于如何在 Android 中高效地与 UI 线程通信?的主要内容,如果未能解决你的问题,请参考以下文章

Android中UI线程与worker线程的通信方法

Android中线程与线程,进程与进程之间如何通信?

Android线程间通信更新UI的方法(重点分析EventBus)

使用 P/Invoke 从 Unity 高效地与非托管代码对话

[Android源码分析] - 异步通信Handler机制

Android 线程间通信