471

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

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

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

4

20 回答 20

547
于 2014-01-15T00:07:41.440 回答
287

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

就我而言,我的申请中没有繁重的过程。我仔细检查了所有内容并删除了那些我认为有点繁重的过程。

我删除了 Fragments、Activity、Libraries,直到只剩下骨架。但问题仍然没有消失。我决定检查资源,发现我使用的一些图标和背景非常大,因为我忘记检查这些资源的大小。

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

于 2015-08-30T10:48:10.597 回答
72

我也有同样的问题。
我的情况是,我使用的是可绘制对象中的背景图像。该特定图像约为 130kB,并在我的 android 应用程序的初始屏幕和主页期间使用。

解决方案- 我只是将该特定图像从 drawables 转移到 drawables-xxx 文件夹,并且能够释放后台占用的大量内存,并且跳过的帧不再跳过。

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

于 2016-04-13T22:39:57.000 回答
24

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

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

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

于 2016-02-02T19:43:12.093 回答
19

我有同样的问题。Android Emulator 在 Android < 6.0 上完美运行。当我使用模拟器 Nexus 5 (Android 6.0) 时,该应用程序I/Choreographer: Skipped frames在日志中的运行速度非常慢。

因此,我通过将 Manifest 文件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,则默认启用硬件加速。

于 2017-11-29T15:54:02.080 回答
18

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

  • 如果可能,请使用多线程编程。即使您的智能手机只有一个内核(如果处理器有两个或更多,线程可以在不同的内核中运行),性能优势也是巨大的。使您的应用程序逻辑与 UI 分离很有用。使用 Java 线程、AsyncTask 或 IntentService。检查这个
  • 阅读并遵循 Android 开发网站的 misc 性能提示。在这里检查
于 2013-08-10T04:47:13.430 回答
8

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

于 2015-09-04T06:50:15.977 回答
7

优化您的图像...不要使用大于 100KB 的图像...图像加载占用过多的 CPU 并导致您的应用程序挂起。

于 2016-07-08T11:52:46.443 回答
7

我有同样的问题。就我而言,我有 2 个嵌套的相对布局。RelativeLayout 总是必须进行两次测量传递。如果嵌套RelativeLayouts,你会得到一个指数测量算法。

于 2016-06-14T08:11:57.680 回答
6

这通常发生在您在主线程中执行大型进程时。跳过少于 200 个的帧是可以的。但是如果跳过的帧超过 200 个,它会减慢应用程序 UI 线程的速度。您可以做的是在一个称为工作线程的新线程中执行这些进程,然后,当您想要访问并使用 UI 线程执行某些操作(例如:使用视图、findView 等执行某些操作)时,您可以使用处理程序或runOnUiThread(我更喜欢这个)为了显示处理结果。这绝对解决了问题。在这种情况下,使用工作线程非常有用,甚至必须使用。

https://stacklearn.ir

于 2019-02-22T15:59:48.630 回答
2

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

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

于 2018-03-22T05:00:32.963 回答
1

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

于 2019-12-05T09:08:37.123 回答
1

正如我所做的那样,我首先首选使用SVG图像而不是所有其他类型,如果不可能的话,请PNG使用JPG一些图像处理工具(例如Adobe PhotoshopFotosizer. 最简单的方法之一是像这样的在线图像压缩工具,它帮助我将所有图像文件减少到其初始大小的近 50%。

于 2021-01-02T08:34:31.853 回答
0

这实际上不是问题。当您长时间使用调试器时会发生这种情况。拆下制动点并再次检查。

于 2022-02-05T01:05:42.847 回答
0

在开发一个在网格布局上使用大量可绘制 png 文件的应用程序时,我遇到了同样的问题。我还尝试尽可能优化我的代码..但它对我没有用..然后我尝试减小那些 png 的大小..并猜测它工作得很好..所以我的建议是减少可绘制资源的大小(如果有)..

于 2016-05-20T04:39:26.020 回答
0

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

于 2016-01-28T16:11:04.667 回答
0

在对这个问题进行了大量研发之后,我得到了解决方案,

就我而言,我使用的是每 2 秒运行一次的服务,并且使用 runonUIThread,我想知道问题是否存在,但根本不存在。我发现的下一个问题是我在 May App 中使用了大图像,这就是问题所在。

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

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

于 2017-10-14T09:02:41.953 回答
0

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

于 2018-08-13T14:12:02.450 回答
0

尚未解决,但会解决。对于我的具有一个可组合功能(按钮)和逻辑来检查设备(模拟器)上是否存在“com.whatsapp”包的小型项目,我在启动模拟器时在同一日志中具有以下内容:

I/Choreographer: Skipped 34 frames!  The application may be doing too much work on its main thread.
于 2021-08-08T13:55:24.767 回答
-1

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

于 2020-08-16T07:14:51.920 回答