我安装了最新版本的SDK(API 16)
并获得了最新的ADT。我现在在logcat中看到了这些消息,我很确定,我以前没有见过。有人对此有想法吗?
06-29 23:11:17.796:我/编舞(691):跳过647帧!应用程序可能在其主线程上做了太多工作。
我进行了搜索,找到了以下链接:http://developer.android.com/reference/android/view/Choreographer.html.这是API 16中引入的一个新类。
我需要知道如何确定我的应用程序可能在做什么“太多的工作”,因为我的所有处理都是在AsyncTask
中完成的。
这是一条信息消息,在许多情况下可能会出现在您的LogCat中。
在我的例子中,它发生在我以编程方式从XML布局文件中扩展多个视图时。该消息本身无害,但可能是以后出现问题的迹象,该问题将使用你的应用程序允许使用的所有RAM,并导致超级邪恶势力接近发生。我已经成长为那种喜欢看到自己的日志警告/信息/无错误的开发人员
所以,这是我自己的经历:
我得到消息:
10-09 01:25:08.373: I/Choreographer(11134): Skipped XXX frames! The application may be doing too much work on its main thread.
... 当我创建自己的自定义“超级复杂多节列表”时,通过从XML中膨胀视图并填充其字段(图像、文本等…)对于来自REST/JSON web服务响应的数据(没有分页功能),此视图将充当行、小节头和节头,方法是将所有这些按正确的顺序添加到线性布局中(在ScrollView中具有垂直方向)。所有这些都是为了模拟具有可单击元素的listView。。。但这是另一个问题。
作为一名负责任的开发人员,您希望让应用程序真正有效地利用系统资源,因此列表的最佳实践(当您的列表不那么复杂时)是使用带有加载程序的ListActivity或ListFragment,并用适配器填充ListView,这应该更有效,事实上是这样,您应该一直这样做,再次。。。如果你的清单不是那么复杂。
解决方案:我在我的REST/JSON web服务上实现了分页,以防止出现“大响应大小”,并且我包装了代码,在AsyncTask上添加了“行”、“节头”和“子节头”视图,以保持主线程冷却。
所以我希望我的经验能帮助其他人打开他们的脑袋,告诉他们这些信息。
快乐的黑客!
我迟到了,但希望这是对这里其他答案的有用补充...
我需要知道如何确定我的应用程序可能在做什么“太多的工作”,因为我的所有处理都是在Async任务中完成的。
以下是所有候选人:
要实际确定具体原因,您需要分析您的应用程序。
我一直试图通过实验和查看代码来理解编舞。
Choreographer的文档以“协调动画、输入和绘图的计时”打开这实际上是一个很好的描述,但其余部分继续过度强调动画。
Choreographer实际上负责执行3种类型的回调,它们按以下顺序运行:
其目的是使无效视图的重新绘制(以及动画的过渡)速度与屏幕vsync相匹配,通常为60fps。
关于跳过帧的警告看起来像是事后才想到的:如果一次通过3个步骤需要超过预期帧持续时间的30倍,则会记录消息,因此您可以期望在日志消息中看到的最小数量是“跳过30帧”;如果每次通过的时间比应该的时间长50%,您仍然会跳过30帧(淘气!)但您不会收到警告。
从涉及的3个步骤中可以清楚地看出,触发警告的不仅仅是动画:用复杂的onDraw方法使大型视图层次结构或视图的重要部分无效可能就足够了。
例如,这将重复触发警告:
public class AnnoyTheChoreographerActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_linear_layout);
ViewGroup root = (ViewGroup) findViewById(R.id.root);
root.addView(new TextView(this){
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
long sleep = (long)(Math.random() * 1000L);
setText("" + sleep);
try {
Thread.sleep(sleep);
} catch (Exception exc) {}
}
});
}
}
... 这会产生如下日志记录:
11-06 09:35:15.865 13721-13721/example I/Choreographer﹕ Skipped 42 frames! The application may be doing too much work on its main thread.
11-06 09:35:17.395 13721-13721/example I/Choreographer﹕ Skipped 59 frames! The application may be doing too much work on its main thread.
11-06 09:35:18.030 13721-13721/example I/Choreographer﹕ Skipped 37 frames! The application may be doing too much work on its main thread.
在绘制过程中,您可以从堆栈中看到,无论您是否正在制作动画,编舞都会参与其中:
例如。AnnoyTheChoreograph活动$1.on抽奖(AnnoyTheChoreograph erActivity.java:25)android.view.View.draw(View.java:13759)
... 有点重复。。。
在android上。看法视图组。android上的drawChild(ViewGroup.java:3169)。看法视图组。android上的dispatchDraw(ViewGroup.java:3039)。看法看法在android上绘制(View.java:13762)。小装置。框架布局。在com上绘制(FrameLayout.java:467)。Android内部的政策实施。PhoneWindow$DecorView。在android上绘制(PhoneWindow.java:2396)。看法看法android上的getDisplayList(View.java:12710)。看法看法android上的getDisplayList(View.java:12754)。看法硬件渲染器$GlRenderer。在android上绘制(HardwareRenderer.java:1144)。看法ViewRootImpl。在android上绘制(ViewRootImpl.java:2273)。看法ViewRootImpl。在android上执行Draw(ViewRootImpl.java:2145)。看法ViewRootImpl。在android上执行Traversals(ViewRootImpl.java:1956)。看法ViewRootImpl。android上的doTraversal(ViewRootImpl.java:1112)。看法ViewRootImpl$TraversalRunnable。在android上运行(ViewRootImpl.java:4472)。看法Choreographer$CallbackRecord。在android上运行(Choreographer.java:725)。看法编舞android上的doCallbacks(Choreographer.java:555)。看法编舞android上的doFrame(Choreographer.java:525)。看法Choreographer$FrameDisplayEventReceiver。在android上运行(Choreographer.java:711)。操作系统。处理程序。android上的handleCallback(Handler.java:615)。操作系统。处理程序。android上的dispatchMessage(Handler.java:92)。操作系统。活套。android上的loop(Looper.java:137)。应用程序。ActivityThread。main(ActivityThread.java:4898)
最后,如果来自其他线程的争用减少了主线程可以完成的工作量,即使您实际上并没有在主线程上完成工作,跳过帧的机会也会显着增加。
在这种情况下,暗示应用程序在主线程上做得太多可能会被认为是误导,但Android确实希望工作线程以低优先级运行,以防止它们耗尽主线程。如果工作线程的优先级较低,那么触发Choreographer警告的唯一方法实际上是在主线程上执行太多操作。
Choreographer允许应用程序将自己连接到vsync,并适当地调整时间以提高性能。
Android view动画在内部使用Choreographer的目的是相同的:正确地计时动画,并可能提高性能。
由于编排器被告知每个vsync事件,它可以判断Choreographer.post*apis传递的Runnables之一是否在一帧时间内没有完成,从而导致帧被跳过。
据我所知,编舞只能检测到跳帧。它无法解释为什么会发生这种情况。
消息“应用程序可能在其主线程上做了太多工作。”可能会产生误导。
问题内容: 我现在不知道该LogCat条目的含义。有人能帮我吗? 问题答案: 其中至少有一个空对象,您不能拥有。 您可以通读源代码,并在此处看到这种情况:
所以我得到了我想理解的代码,但我不知道这个操作符的含义: 如果你们能告诉我就太棒了谢谢
我是Java的初学者,简单的东西对我来说是新的。除我的水平外,谷歌不想搜索这样的关键词,比如“- 我在这里找到的。所以我认为这个代码是正确的。 请帮助我理解这个表达是什么意思?
技术规格 电池:3 x AAA 1.5V 碱性电池 最大称重能力:180 千克(397.8 磅) 体重显示分辨率:0.1 千克 / 0.2 磅 工作温度:0°C 至 45°C (32°F 至 113°F) 更换电池 Polar Balance 体重秤使用三个 AAA 1.5V 碱性电池。请使用已提供的电池。在您需要更换电池时,请勿使用充电电池或将新旧电池混合使用。 打开电池盖,取出旧电池。 将新电
问题内容: 我正在JavaFx中创建一个应用程序,如果要打开任何子阶段,则应在其中进行操作,然后应在父阶段的中心打开它。我正在尝试使用它来执行此操作,但是它将子级分配到屏幕的中心,而不是父级的中心。如何将子阶段分配给父阶段的中心? 问题答案: 您可以使用父级的X / Y / width / height属性来执行此操作。除了使用,您可以执行以下操作: