我是Android SDK / API环境的新手。这是我第一次尝试绘制图表。我尝试使用3个不同的免费库运行仿真器的各种示例代码,但布局屏幕上没有任何显示。logcat重复以下消息:
W / Trace(1378):nativeGetEnabledTags中的异常值:0 I / Choreographer(1378):跳过了55帧!该应用程序可能在其主线程上做太多工作。
当我运行与许可库的评估副本有关的示例代码时,问题仍然存在,并且图表起作用了。
我是Android SDK / API环境的新手。这是我第一次尝试绘制图表。我尝试使用3个不同的免费库运行仿真器的各种示例代码,但布局屏幕上没有任何显示。logcat重复以下消息:
W / Trace(1378):nativeGetEnabledTags中的异常值:0 I / Choreographer(1378):跳过了55帧!该应用程序可能在其主线程上做太多工作。
当我运行与许可库的评估副本有关的示例代码时,问题仍然存在,并且图表起作用了。
Answers:
任何开始开发android应用程序的人都会在logcat “ Choreographer(abc):跳过xx帧!该应用程序可能在其主线程上做过多的工作。” 因此,这实际上意味着什么,为什么要引起关注以及如何解决它。
这意味着您的代码需要花费很长时间进行处理,因此会跳过帧。这可能是因为您在应用程序或数据库访问的核心处进行了大量繁重的处理,或导致线程执行错误的任何其他操作停一会儿。
这是更详细的说明:
Choreographer允许应用程序将自身连接至vsync,并适当安排时间以提高性能。
Android视图动画在内部使用Choreographer来达到相同的目的:正确地设置动画时间并可能改善性能。
由于Choreographer被告知每个vsync事件,因此我可以判断Choreographer.post * api传递的Runnable之一是否在一帧时间内未完成,从而导致跳过帧。
以我的理解,编舞只能检测到跳帧。它无法说明为什么会这样。
消息“应用程序可能在其主线程上做过多的工作。” 可能会产生误导。
来源: Logcat中编舞者消息的含义
为什么要担心
当此消息在android模拟器上弹出并且跳过的帧数很小(<100)时,您可以安全地押注模拟器运行缓慢-这几乎总是发生。但是,如果跳过的帧数很大且在300+左右,那么代码可能会出现严重的问题。与ios和Windows设备不同,Android设备具有多种硬件。RAM和CPU有所不同,如果要在所有设备上获得合理的性能和用户体验,则需要修复此问题。跳过帧时,UI缓慢且缓慢,这不是理想的用户体验。
如何修复
要解决此问题,需要确定存在或可能发生长时间处理的节点。最好的方法是执行与主UI线程分开的线程中的大小无关的所有处理。因此,无论是从SQLite数据库访问数据,还是做一些硬性数学运算,或者只是对数组进行排序–都可以在另一个线程中完成
现在这里有一个问题,您将创建一个用于执行这些操作的新线程,并且在您运行应用程序时,它会崩溃,提示“只有创建视图层次结构的原始线程才能触摸其视图”。您需要知道以下事实:Android中的UI只能由主线程或UI线程更改。任何其他尝试这样做的线程都会失败,并因该错误而崩溃。您需要做的是在runOnUiThread内创建一个新的Runnable,然后在该Runnable中执行涉及UI的所有操作。在此处查找示例。
所以我们有Thread和Runnable来处理主线程中的数据,还有什么呢?android中有AsyncTask,它可以在UI线程上执行长时间的处理。当您的应用程序是数据驱动的或Web api驱动的,或者使用复杂的UI(例如使用Canvas构建的UI)时,这是最有用的。AsyncTask的功能是允许在后台执行操作,一旦完成处理,您就可以简单地在UI上执行所需的操作,而不会造成任何滞后效果。这是可能的,因为AsyncTask本身是从Activity的UI线程派生的-您通过AsyncTask在UI上执行的所有操作都是与主UI线程不同的线程,不妨碍用户交互。
因此,这是制作流畅的android应用程序所需的知识,据我所知,每个初学者都会在他的控制台上收到此消息。
正如其他人在上面回答的那样,“跳过了55帧!” 意味着您的应用程序正在处理一些繁重的工作。
就我而言,我的申请没有繁琐的过程。我对所有内容进行了两次和三次检查,并删除了我认为有些繁重的那些过程。
我删除了“片段”,“活动”和“库”,直到只剩下骨骼。但是问题仍然没有解决。我决定检查资源,发现我使用的一些图标和背景很大,因为我忘记了检查这些资源的大小。
因此,我的建议是,如果以上答案均无济于事,您还可以检查资源文件的大小。
我也有同样的问题。
我的情况是我正在使用可绘制的背景图像。该特定图像约为130kB,并在我的android应用程序的启动屏幕和主页中使用。
解决方案 -我只是将特定图像从可绘制对象移到了drawables-xxx文件夹,并且可以释放大量在后台占用的内存,并且跳过的帧不再被跳过。
更新使用“ nodp”可绘制资源文件夹存储背景可绘制文件。
密度合格的可绘制文件夹或drawable-nodpi是否优先?
drawable-xxxhdpi
,而不是drawable
什么大大减少了使用的内存(小于〜70%)。同样要知道的是,相同尺寸的屏幕的DPI尺寸也有所不同。在它们之间的像素的比例是ldpi = 1:0.75
,mdpi = 1:1
,hdpi = 1:1.5
,xhdpi = 1:2
,xxhdpi = 1:3
,xxxhdpi = 1:4
。通过使用该drawable-xxxhdpi
文件夹,您可以将图像缩小到设备的屏幕尺寸,从而减少内存和CPU消耗。
drawable
移到会drawable-nodpi
阻止应用程序获取Out of Memory Error
。
UI线程延迟的另一个常见原因是SharedPreferences访问。PreferenceManager.getSharedPreferences
首次调用a 和其他类似方法时,关联的.xml文件将立即加载并在同一线程中进行解析。
解决此问题的一种好方法是从后台线程中首先触发SharedPreference加载,该加载应尽早开始(例如,从onCreate
Application类的加载)。这样,首选项对象可能已经在您要使用它的时候构建了。
不幸的是,有时在启动的早期阶段(例如,在初始Activity或什至是应用程序本身)需要读取首选项文件。在这种情况下,仍然有可能避免使用暂停UI MessageQueue.IdleHandler
。完成您需要在主线程上执行的所有其他操作,然后在活动完全绘制之后,安装IdleHandler来执行代码。在该Runnable中,您应该能够访问SharedPreferences,而不会延迟太多的绘制操作并使Choreographer不满意。
我有同样的问题。Android Emulator在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>
当您在主线程中执行大型进程时,通常会发生这种情况。可以跳过少于200个的帧。但是,如果跳过的帧超过200个,则可能会减慢您的应用程序UI线程的速度。您可以做的是在称为工作线程的新线程中进行这些处理,然后,当您要访问并使用UI线程(例如:对视图,findView等进行操作)时,可以使用处理程序或runOnUiThread(我更喜欢这个)以显示处理结果。这绝对解决了问题。在这种情况下,使用工作线程非常有用,甚至必须使用。
我有同样的问题。当我在另一台计算机上运行代码时,它运行良好。但是,在我的系统上,它显示“应用程序可能在其主线程上做太多工作”。
我通过重新启动Android Studio解决了我的问题[文件->无效的缓存/重新启动->单击“无效并重新启动”]。
我的应用有同样的问题。但是除了显示卡片列表和文本之外,它没有做其他事情。什么都没有在后台运行。但是,经过一番调查后,发现卡背景的图像集引起了这种情况,即使它很小(350kb)。然后,我使用http://romannurik.github.io/AndroidAssetStudio/index.html将图像转换为9patch图像
。
这对我有用。
在这个问题上做了很多研发之后,我得到了解决方案,
以我为例,我使用的Service将每2秒运行一次,并且使用runonUIThread,我想知道问题在那里但根本没有。我发现的下一个问题是,我可能在May App中使用大图像,这就是问题所在。
我删除了图像并设置了新图像。
结论:-查看您的代码,您使用的原始文件是否很大。
在开发在网格布局上使用大量可绘制png文件的应用程序时遇到了同样的问题。我还尝试了尽可能优化我的代码..但是它对我没有用。可绘制资源的大小(如果有)。