提问者:小点点

应用程序可能在其主线程上做了太多的工作


我是Android SDK/API环境的新手。这是我第一次试着画一张图/图表。我尝试使用3个不同的免费库在模拟器上运行不同类型的示例代码,但布局屏幕上没有显示任何内容。logcat将重复以下消息:

 W/Trace(1378): Unexpected value from nativeGetEnabledTags: 0
 I/Choreographer(1378): Skipped 55 frames!  The application may be doing too much work on its main thread. 

当我运行与一个许可库的评估副本相关的示例代码时,问题并没有持续存在,并且图表工作了。


共1个答案

匿名用户

摘自:Android UI:修复跳过的帧

任何一个开始开发android应用程序的人都会在logcat上看到这条消息“编导(abc):跳过xx帧!应用程序可能在它的主线程上做了太多的工作。“那么它实际上意味着什么,为什么你应该关心,以及如何解决它。

这意味着您的代码需要很长的时间来处理,因此帧会被跳过,这可能是因为您在应用程序的核心进行了大量的处理,或者是DB访问,或者是任何其他导致线程停止一段时间的事情。

这里有更详细的解释:

Choreographer允许应用程序将自己连接到vsync,并适当地定时以提高性能。

Android view animations内部使用Choreographer的目的是相同的:正确地为动画计时,并可能提高性能。

由于Choreographer会被告知每一个vsync事件,所以我可以判断Choreographer.post*API传递的一个Runnables是否没有在一帧时间内完成,从而导致帧被跳过。

根据我的理解,编导只能检测跳帧。它无法说明为什么会发生这种情况。

“应用程序可能在其主线程上做了太多的工作.”的消息可能会产生误导。

来源:Logcat中编舞信息的含义

你为什么要担心

当这个消息在android模拟器上弹出,并且跳过的帧数相当少(<100),那么您可以放心地打赌模拟器是慢的--几乎所有的情况都是这样。但是,如果跳过的帧数很大,大约是300+,那么代码就会出现一些严重的问题。与ios和windows设备不同的是,Android设备拥有大量的硬件。RAM和CPU是不同的,如果你想要一个合理的性能和用户体验在所有的设备,那么你需要修复这个东西。跳过帧时,UI会变得缓慢和滞后,这不是理想的用户体验。

如何修复

解决这一问题需要识别存在或可能发生长时间处理的节点。最好的方法是在一个独立于主UI线程的线程中完成所有的处理,无论处理大小。因此,无论是从SQLite数据库访问数据,还是进行一些核心数学运算,或者只是对数组进行排序--在不同的线程中进行

现在这里有一个问题,您将创建一个执行这些操作的新线程,当您运行应用程序时,它会崩溃,说“只有创建视图层次结构的原始线程可以触摸它的视图”。您需要知道这样一个事实:android中的UI可以由主线程或仅由UI线程进行更改。尝试这样做的任何其他线程都将失败,并以此错误崩溃。您需要做的是在runOnUiThread中创建一个新的Runnable,在这个Runnable中,您应该执行涉及UI的所有操作。在这里找到一个例子。

所以我们有线程和Runnable来处理主线程之外的数据,还有什么呢?android中有AsyncTask,它允许在UI线程上执行长时间的进程。当您的应用程序是数据驱动或web api驱动的,或者使用复杂的UI(比如使用canvas构建的UI)时,这是最有用的。AsyncTask的强大之处在于,它允许在后台执行操作,一旦完成处理,您就可以在UI上执行所需的操作,而不会造成任何滞后效果。这是可能的,因为AsyncTask是从activity的UI线程派生出来的--通过AsyncTask在UI上执行的所有操作都是与主UI线程不同的线程,不会妨碍用户交互。

因此,这是你需要知道的,以使android应用程序流畅,据我所知,每个初学者都会得到这条消息在他的控制台。

相关问题