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

我是Android SDK / API环境的新手。 这是我试图绘制一个情节/图表的第一个。 我尝试使用3个不同的免费库运行不同types的示例代码模拟器,布局屏幕上没有任何显示。 logcat正在重复以下消息:

  W / Trace(1378):来自nativeGetEnabledTags的意外值:0
 我/编舞(1378):跳过55帧! 应用程序可能在其主线程上做了太多的工作。 

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

取自: Android用户界面:修复跳过的框架

任何开始开发android应用程序的人都会在logcat上看到这条消息“Choreographer(abc):跳过了xx框架! 应用程序可能在其主线程上做了太多的工作。“那么它究竟意味着什么,为什么要关心以及如何解决它。

这意味着你的代码需要花费很长时间来处理,而框架也会因此而被跳过,这可能是因为你在应用程序或数据库访问的核心或者其他导致线程停一会儿。 这里是一个更详细的解释:

编排器允许应用程序将自己连接到vsync,并适当地设置时间以提高性能。

Android视图animation在内部使用Choreographer来达到相同的目的:适当的时间animation并可能提高性能。

由于Choreographer被告知关于每个vsync事件,我可以判断一个帧是否被一个帧时间完成,是否有一个Runnables被Choreographer.post * apis传递,导致帧被跳过。

在我的理解编舞只能检测跳帧。 没有办法解释为什么会发生这种情况。

“应用程序在其主线上可能做了太多工作”的消息可能会引起误解。

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

为什么你应该关心

当这个消息在android模拟器上popup,并且跳过的帧数量相当小(<100),那么你可以安全地下注模拟器正在缓慢 – 这几乎发生在所有的时间。 但是,如果跳过的帧数量很大,并且大于300+,那么代码可能会有一些严重的问题。 与ios和windows设备不同,Android设备有大量的硬件。 RAM和CPU各不相同,如果你想在所有的设备上有一个合理的性能和用户体验,那么你需要解决这个问题。 当跳过帧时,UI太慢而且迟缓,这不是一个理想的用户体验。

如何解决它

解决这个问题需要识别有可能或可能发生长时间处理的节点。 最好的办法是做一切处理,无论在主UI线程分离的线程多大或小。 所以无论是从SQLite数据库访问数据或做一些硬核math或简单地sorting数组 – 在不同的线程

现在有一个问题,你将创build一个新的线程来执行这些操作,当你运行你的应用程序时,它会崩溃,说:“只有创build一个视图层次结构的原始线程可以触及其视图”。 你需要知道这个事实,android中的UI可以被主线程或UI线程改变。 任何其他尝试这样做的线程都会失败,并会崩溃。 你需要做的是在runOnUiThread内部创build一个新的Runnable,在这个Runnable中你应该完成所有涉及UI的操作。 在这里find一个例子。

所以我们有Thread和Runnable来处理主线程的数据,还有什么? 在android中有AsyncTask,可以在UI线程上做很长时间的处理。 当你的应用程序是数据驱动或web api驱动或使用像使用Canvas构build的复杂UI时,这是最有用的。 AsyncTask的强大之处在于可以在后台执行任何操作,一旦完成处理,您可以简单地在UI上执行所需的操作,而不会造成任何滞后效应。 这是可能的,因为AsyncTask从Activity的UI线程派生自己 – 通过AsyncTask在UI上完成的所有操作都是与主UI线程不同的线程,对用户交互没有阻碍。

所以这就是你需要知道的平滑的Android应用程序,据我所知,每个初学者在他的控制台上得到这个消息。

我不写这个来获得更多的声誉。 我只想分享我的情况。 正如其他人回答上面,“跳过55帧!” 意味着一些重要的处理在您的应用程序。 对我来说,我的申请没有繁重的过程。 我加倍和三重检查一切,并删除我认为有点沉重的过程。 我删除片段,活动,库,直到只剩下骨架。 但问题仍然没有消失。 我决定检查资源,发现我使用的一些图标和背景非常大,因为我忘记检查这些资源的大小。

所以,我的build议是,如果没有上述答案的帮助,你也可以检查你的资源文件的大小。

我也有同样的问题。
我的情况是,我使用的背景图像是可绘制的。这个特定的图像是大约130kB,并在我的android应用程序的启animation面和主页中使用。

解决scheme – 我只是把那个特殊的图像从drawables中移出drawables-xxx文件夹,并且能够释放大量在后台占用的内存,跳过的帧不再跳过。

更新使用“nodp”drawable资源文件夹来存储背景drawables文件。
将密度合格的可绘制文件夹或drawable-nodpi优先?

尝试使用以下策略来提高应用性能:

  • 如果可能的话,使用multithreading编程。 即使你的智能手机有一个内核(如果处理器有两个或多个内核,线程可以在不同内核中运行),性能优势也是巨大的。 使您的应用程序逻辑与UI分离很有用。 使用Java线程,AsyncTask或IntentService。 检查这个 。
  • 阅读并遵循Android开发网站的杂项性能提示。 在这里检查 。

延迟UI线程的另一个常见原因是SharedPreferences访问。 当您第一次调用PreferenceManager.getSharedPreferences和其他类似的方法时,关联的.xml文件将立即在同一个线程中加载和分析。

解决这个问题的好办法之一就是触发后台线程的第一个SharedPreference加载,尽早启动(例如从你的Application类的onCreate )。 这样偏好对象可能已经被你想要使用它的时间构造了。

不幸的是,在启动的早期阶段(例如,在初始活动甚至应用程序本身),有时需要阅读首选项文件。 在这种情况下,仍然可以通过使用MessageQueue.IdleHandler来避免拖延UI。 在主线程上执行其他任何你需要执行的操作,然后安装IdleHandler来完成你的Activity的绘制。 在该Runnable中,您应该能够访问SharedPreferences,而不会拖延太多的绘图操作并使编舞者不高兴。

我不是专家,但是当我想从我的android应用程序发送数据到Web服务器时,我得到了这个debugging消息。 虽然我使用了AsyncTask类,并在后台做了数据传输,为了从服务器获取结果数据,我使用了AsyncTask类的get()方法,这使得UI同步,这意味着您的UI将等待太久。 所以我的build议是让你的应用程序在单独的线程上完成每个面向networking的任务。

我有同样的问题。 就我而言,我有两个嵌套的相对布局。 RelativeLayout总是要做两个度量。 如果你嵌套RelativeLayouts,你会得到一个指数测量algorithm。

优化你的图片…不要使用大于100KB的图片…图片加载需要太多的CPU,导致你的应用程序挂起。

我的应用程序有同样的问题 但是除了在其上显示卡片和文本列表之外,没有其他的做法。 没有在后台运行。 但经过一番调查后发现,卡片背景的图片是这样造成的,尽pipe它很小(350kb)。 然后我使用http://romannurik.github.io/AndroidAssetStudio/index.html将图像转换为9patch图像。;
这对我有效。

在开发一个在网格布局中使用大量可绘制png文件的应用程序时,我得到了同样的问题。 我也尝试尽可能优化我的代码..但它没有为我工作..然后,我试图减less这些PNG的大小,并猜测它的工作绝对好..所以我的build议是减less可绘制资源的大小,如果有的话。

我甚至有同样的问题,只是清理项目帮助。 简单地说它删除了构build目录,删除了预编译的文件。

在对这个问题做了大量的研究之后,我得到了解决scheme,

在我的情况下,我使用服务,将运行每2秒和runonUIThread,我想知道问题在那里,但根本没有。 我发现的下一个问题是,我在may应用中使用大型图像,这就是问题所在。

我删除了图像,并设置新的图像。

结论: – 看看你的代码是否有任何你使用的原始文件的大小。

您可以使用Glide库来加载图像..它会加载图像在后台线程..