我正在处理的应用程序正在以非常高的速率(每100毫秒)接收数据。数据由后台线程接收,我需要在活动中显示它。
我使用处理程序从后台线程到主线程发布数据。但过了一段时间,我们开始看到延迟。
延迟
后台线程以100ms的间隔接收和发送数据给处理器。但是主线程循环器忙于等待FrameHandler完成它的工作。因此,我的消息被延迟处理。
下面是循环日志:
com.example.app。MainActivity$4 -是我的应用程序的自定义处理程序
android.view。Choreographer$FrameHandler - OS框架处理程序
09-08 14:52:02.465 15397 15397 D main_loop:>>>>调度到处理程序(com.example.app.MainActivity$4) {3b4862a} null: 102
09-08 14:52:02.467 15397 15397 D main_loop: <<<<完成处理程序(com.example.app.MainActivity$4) {3b4862a} null
我的应用程序花了2ms来处理一个数据
09-08 14:52:02.467 15397 15397 D main_loop:>>>>调度到处理器(android.view. choreographer $FrameHandler) {6eab416} android.view。编排FrameDisplayEventReceiver@3d19197美元:0
09-08 14:52:06.080 15397 15397 D main_loop: <<<<完成处理(android.view.Choreographer$FrameHandler) {6eab416} android.view.Choreographer$FrameDisplayEventReceiver@3d19197
FrameHandler耗时4秒完成处理。
09-08 14:52:06.080 15397 15397 D main_loop:>>>>调度到处理程序(com.example.app.MainActivity$4) {3b4862a} null: 102
09-08 14:52:06.083 15397 15397 D main_loop: <<<<完成处理程序(com.example.app.MainActivity$4) {3b4862a} null
我们如何减少帧处理程序或任何替代从后台线程到主线程的数据所花费的时间?
在没有看到代码的情况下很难提出替代方案,但解释本身很简单。你给编舞的压力太大了。主线程处理程序在每次屏幕更新时处理它们的消息队列。但你触发屏幕变化,所以更多的更新。在某些情况下,在下一帧之前要完成的工作量太多,而有些帧会被跳过。所以下一个消息被延迟,更多的消息来了,得到更多的延迟……你懂的。
如果您既不能改变消息的频率,也不能改变消息的数量,我建议将它们从编排器中移除。将代码封装到一个类中,用回调执行UI更新,并使用runOnUIThread()从活动中实例化它(或设置回调),这样您就可以跳过队列:
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) {
mHandler.post(action);
} else {
action.run();
}
}
事件总线可能有助于事件交付。如果您正在更新一个recyclerView,那么直接访问适配器数据也可以工作。正如我所说,这取决于你实际在做什么。
没有看到你的代码,我只能猜测。我想你不会喜欢我的猜测,然而,这很可能是真的。如果你每十分之一秒检查一次数据,android很可能会识别到这一点,并认为这是毫无意义的,并降低应用程序的速度。另一种可能性是,您可能不得不等待代码尝试接收数据的时间超过十分之一秒,这将减慢整个线程的速度。
就当我猜吧。