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

我是Android SDK/API环境的新手。这是我第一次试着画一个图表。我尝试在模拟器上使用3个不同的免费库运行不同种类的示例代码,没有显示在布局屏幕上。日志猫正在重复如下信息:

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.

当我运行一个与授权库的评估副本相关的示例代码时,这个问题并没有持续存在,图表也正常工作。

558931 次浏览

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

  • 尽可能使用多线程编程。即使你的智能手机只有一个核(如果处理器有两个或更多核,线程可以在不同的核上运行),性能上的好处也是巨大的。让你的应用逻辑与UI分离是很有用的。使用Java线程,AsyncTask或IntentService。检查这个
  • 阅读并遵循Android开发网站的各种性能提示。检查在这里

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

任何开始开发android应用程序的人都会看到这条消息 logcat " Choreographer(abc):跳过xx帧!申请可以是 在主线程上做了太多工作。那么它实际上是 意思是,你为什么要关心它,以及如何解决它
这意味着你的代码需要很长时间来处理和帧 都因为它而被跳过,这可能是因为一些沉重的 您在应用程序或数据库的核心所做的处理 访问或任何其他事情,导致线程停止一段时间。< /强> < / p >

下面是更详细的解释:

Choreographer让应用程序连接自己的垂直同步,和

Android视图动画内部使用相同的Choreographer 目的:适当的时间动画和可能的改进 性能。< / p >

因为Choreographer被告知每个垂直同步事件,我可以告诉如果 一个奔跑者从编舞家身边走过。发布* api 没有在一帧时间内完成,导致帧被跳过

在我的理解Choreographer只能检测帧跳跃。 它没有办法告诉为什么会发生这种情况

消息"应用程序可能在它的main上做了太多的工作 线程。

< p >来源:
在Logcat中编排器消息的含义 < / >强

你为什么要担心

当这个消息在android上弹出 模拟器和跳过的帧数是相当小的(<100)然后 你可以打个保险赌模拟器会变慢——这确实发生了 几乎所有的时间。但如果跳过的帧数较大 在300+的情况下,可能会有一些严重的问题 你的代码。与ios不同,Android设备有大量的硬件 还有Windows设备。内存和CPU是不同的,如果你想要 合理的性能和用户体验在所有设备上然后你 需要修理这个东西。当跳过帧时,UI会变慢 滞后,这不是一个理想的用户体验

如何解决

修复此问题需要识别存在或的节点 可能会发生长时间的处理。最好的办法就是去做 所有的处理无论大小都在一个线程中分开 从主UI线程。因此,它是访问数据形式SQLite数据库或 做一些硬核数学或简单的排序数组-在一个 不同的线程< / p > 现在这里有一个陷阱,你将创建一个新的线程来做 这些操作和当你运行你的应用程序时,它将崩溃 说“只有创建视图层次结构的原始线程可以。 触摸它的视图”。你需要知道android中的UI可以 仅由主线程或UI线程更改。任何其他线程 它试图这样做,失败并崩溃与此错误。你 需要做的是在runOnUiThread和内部创建一个新的Runnable 这个可运行的,你应该做所有涉及到UI的操作。找到 一个例子在这里.

.

. 所以我们有Thread和Runnable来处理主线程外的数据, 还有什么?android中有AsyncTask,允许长时间执行 UI线程上的进程。这是最有用的 应用程序是数据驱动或web api驱动或使用复杂的UI 比如那些使用Canvas构建的。AsyncTask的强大之处在于 允许在后台做事情,一旦你完成了 处理,您可以简单地在UI上执行所需的操作而无需 造成任何滞后效应。这是可能的,因为AsyncTask 派生自Activity的UI线程——你所做的所有操作 on UI via AsyncTask是一个不同于主UI的线程

.线程,不妨碍用户交互 这就是制作流畅的android所需要知道的 据我所知,每个初学者都会在他的应用程序上得到这条信息 控制台。< / p >

正如上面其他人回答的那样,“跳过55帧!”意味着应用程序中有一些繁重的处理。

对于我的情况,我的申请过程并不繁琐。我反复检查了所有内容,并删除了那些我认为有点沉重的过程。

我删除了片段、活动、库,直到只剩下骨架。但是问题仍然没有消失。我决定检查一下资源,发现我使用的一些图标和背景相当大,因为我忘记检查这些资源的大小。

因此,我的建议是,如果以上答案都没有帮助,您也可以检查您的资源文件大小。

我不是专家,但当我想从我的android应用程序发送数据到web服务器时,我得到了这个调试消息。虽然我使用AsyncTask类并在后台进行数据传输,但为了从服务器获取结果数据,我使用了AsyncTask类的get()方法,这使得UI同步,这意味着你的UI将等待太长时间。所以我的建议是让你的应用程序在一个单独的线程上执行每个面向网络的任务。

我的应用程序也有同样的问题。但除了显示卡片列表和文本之外,它并没有做其他事情。没有在后台运行。但随后经过一些调查发现,卡片背景的图像设置导致了这种情况,尽管它很小(350kb)。然后我将图像转换为9patch图像使用 http://romannurik.github.io/AndroidAssetStudio/index.html
这对我很管用。

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

解决这个问题的一个好方法是从后台线程触发第一次SharedPreference加载,尽可能早地开始(例如从你的Application类的onCreate开始)。这样,在您想要使用首选项对象时,首选项对象可能已经构造好了。

不幸的是,有时在启动的早期阶段读取首选项文件是必要的(例如在初始活动甚至应用程序本身)。在这种情况下,仍然可以通过使用MessageQueue.IdleHandler来避免UI暂停。在主线程上执行其他所有需要执行的操作,然后在完全绘制完Activity之后安装IdleHandler来执行代码。在这个Runnable中,您应该能够访问SharedPreferences,而不会延迟太多的绘图操作,从而使Choreographer不高兴。

我也有同样的问题 我的是一个案例,我使用的背景图像是在绘图。这个特定的图像大约有130kB,在我的android应用程序的启动画面和主页中使用

解决方案 -我只是把这个特定的图像从drawables转移到drawables-xxx文件夹,并且能够释放大量的内存占用在背景和跳过帧不再跳过。

更新使用'nodp'可绘制资源文件夹来存储背景可绘制图 文件。
密度限定的可绘制文件夹还是drawable-nodpi优先? < / p >

我在开发一个在网格布局上使用大量可绘制png文件的应用程序时遇到了同样的问题。我也尽量优化我的代码。但这对我来说行不通。然后我尝试减小这些png的大小。我猜它工作得绝对很好。所以我的建议是减少可绘制资源的大小。

我也有同样的问题。在我的情况下,我有2个嵌套的相对布局。RelativeLayout总是要做两个措施通过。如果你嵌套RelativeLayouts,你会得到一个指数测量算法。

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

在这个问题上做了很多研究之后,我得到了解决方案,

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

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

结论:-检查你的代码是否有任何你正在使用的原始文件是大的。

我也有同样的问题。Android模拟器在Android <上工作完美;6.0. 当我使用模拟器Nexus 5 (Android 6.0)时,应用程序在日志中I/Choreographer: Skipped frames工作得非常慢。

所以,我解决了这个问题,在清单文件hardwareAccelerated选项更改为true,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication">


<application android:hardwareAccelerated="true">
...
</application>
</manifest>

2022年1月更新。根据@M的评论。Ed:如果你的目标是api >= 14,硬件加速默认是启用

我也有同样的问题。当我在另一台计算机上运行这段代码时,它工作得很好。然而,在我的系统上,它显示“应用程序可能在主线程上做了太多的工作”。

我通过重新启动Android工作室解决了我的问题[文件->无效缓存/重新启动->单击“无效并重新启动”]。

首先阅读警告。它表示在主线程上有更多的负载。所以你要做的就是在线程中运行有更多工作的函数。

这通常发生在你在主线程中执行大进程的时候。跳过小于200帧的帧是可以的。但是如果你有超过200个跳过的帧,它会减慢你的应用程序UI线程。你能做的是在一个叫做工作线程的新线程中做这些进程,在那之后,当你想访问和做一些与UI线程(例如:做一些与视图,findView等…)你可以使用handler或runOnUiThread(我更喜欢这个)来显示处理结果。 这绝对解决了问题。在这种情况下,使用工作线程非常有用,甚至必须使用

< a href = " https://stacklearn。Ir " rel="nofollow noreferrer">https://stacklearn.ir

在我的例子中,这是因为我不小心在一个方法上设置了一个断点。一旦我清除了它,消息就消失了,性能提高了很多。

如果在应用程序中使用async/await功能,这是正常的。

因为我首先最好使用SVG图像而不是所有其他类型的图像,如果不可能,使用一些图像处理工具(如Adobe PhotoshopFotosizer)压缩所有PNGJPG资源。最简单的方法之一是在线图像压缩工具,如,它帮助我将所有图像文件减少到初始大小的50%。

还没有解决,但会解决的。对于我的小项目,有一个可组合的功能(按钮)和逻辑来检查是否"com.whatsapp"在启动模拟器时,我在相同的日志中有以下内容:

I/Choreographer: Skipped 34 frames!  The application may be doing too much work on its main thread.

这其实不是问题。当调试器运行了很长时间时,就会发生这种情况。取下制动点并再次检查。

对我来说,这是RoundedBackgroundColorSpan !在textview中,我删除了它(燃烧我的大脑来找到它,因为它没有出现在像Pixel 4 Xl或三星note 10+这样的真实智能手机中,也没有出现在模拟器中,但在芯片设备中如此缓慢的视图)。