我安装了最新版本的SDK (API 16)
并获得了最新的ADT。我现在在logcat中看到这些消息,我很确定,我以前没见过。有没有人对此有所了解?
06-29 23:11:17.796:I / Choreographer(691):跳过647帧!该 应用程序可能在其主线程上做了太多工作。
我进行了搜索并找到了这个链接: http://developer.android.com/reference/android/view/Choreographer.html。这是API 16中引入的新类。
我需要知道如何确定我的应用程序可能做的“太多工作”,因为我的所有处理工作都在AsyncTask
完成。
答案 0 :(得分:132)
Choreographer允许应用程序将自己连接到vsync,并正确计时以提高性能。
Android视图动画在内部使用Choreographer用于同一目的:正确计时动画并可能提高性能。
由于Choreographer被告知每个vsync事件,我可以判断Choreographer.post * apis传递的其中一个Runnables是否在一帧的时间内完成,导致跳过帧。
在我的理解中,编舞者只能检测跳帧。它无法解释为什么会发生这种情况。
消息“应用程序可能在其主线程上做了太多工作。”可能会产生误导。
答案 1 :(得分:64)
我已经迟到了,但希望这是对其他答案的有用补充......
我需要知道如何确定"过多的工作"我的应用程序可能正在执行,因为我的所有处理都是在AsyncTasks中完成的。
以下是所有候选人:
Uri
上加载drawable,膨胀布局和设置ImageView
都构成主线程上的IO) / LI>
View
层次结构View
层次结构的大部分无效onDraw
&#39>中的昂贵View
方法AsyncTask
"背景"默认情况下,java.lang.Thread
不)实际确定您需要对应用进行个人资料的具体原因。
我一直试图通过试验和查看code来了解编舞。
Choreographer的文档打开时使用"协调动画,输入和绘图的时间。"这实际上是一个很好的描述,但其余的继续过分强调动画。
Choreographer实际上负责执行3种类型的回调,它们按以下顺序运行:
目的是将重新绘制无效视图(和补间动画)的速率与屏幕vsync相匹配 - 通常为60fps。
关于跳过帧的警告看起来像是事后的想法:如果单个通过3个步骤所需的帧时间超过30倍,则会记录该消息,因此您可以预期看到的最小数字在日志消息中"跳过 30 帧&#34 ;;如果每个传递的时间比它应该延长50%,你仍然会跳过30帧(顽皮!),但你不会被警告。
从所涉及的3个步骤可以清楚地看出,它不仅仅是可以触发警告的动画:使用复杂的onDraw方法使大View
层次结构的重要部分或View
无效可能就够了。
例如,这将反复触发警告:
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.
你可以在onDraw
期间从堆栈中看到编舞者是否参与,无论你是否在制作动画:
at example.AnnoyTheChoreographerActivity $ 1.onDraw(AnnoyTheChoreographerActivity.java:25) 在android.view.View.draw(View.java:13759)
......相当多的重复...
在android.view.ViewGroup.drawChild(ViewGroup.java:3169) 在android.view.ViewGroup.dispatchDraw(ViewGroup.java:3039) 在android.view.View.draw(View.java:13762) 在android.widget.FrameLayout.draw(FrameLayout.java:467) 在com.android.internal.policy.impl.PhoneWindow $ DecorView.draw(PhoneWindow.java:2396) 在android.view.View.getDisplayList(View.java:12710) 在android.view.View.getDisplayList(View.java:12754) 在android.view.HardwareRenderer $ GlRenderer.draw(HardwareRenderer.java:1144) 在android.view.ViewRootImpl.draw(ViewRootImpl.java:2273) 在android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2145) 在android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1956) 在android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1112) 在android.view.ViewRootImpl $ TraversalRunnable.run(ViewRootImpl.java:4472) 在android.view.Choreographer $ CallbackRecord.run(Choreographer.java:725) 在android.view.Choreographer.doCallbacks(Choreographer.java:555) 在android.view.Choreographer.doFrame(Choreographer.java:525) 在android.view.Choreographer $ FrameDisplayEventReceiver.run(Choreographer.java:711) 在android.os.Handler.handleCallback(Handler.java:615) 在android.os.Handler.dispatchMessage(Handler.java:92) 在android.os.Looper.loop(Looper.java:137) 在android.app.ActivityThread.main(ActivityThread.java:4898)
最后,如果来自其他线程的争用减少了主线程可以完成的工作量,即使您没有在主线程上进行工作,跳帧的可能性也会大大增加。
在这种情况下,建议应用程序在主线程上执行过多操作可能会被误导,但Android really wants worker threads to run at low priority可能会阻止它们使主线程挨饿。如果你的工作线程是低优先级,那么触发Choreographer警告的唯一方法就是在主线程上做太多。
答案 2 :(得分:24)
如果在很多情况下可能会在LogCat中弹出一条信息消息。
就我而言,当我以编程方式从XML布局文件中膨胀多个视图时,就发生了这种情况。这条消息本身是无害的,但可能是后来问题的标志,它将使用你的应用程序允许使用的所有RAM,并导致巨大的邪恶力量关闭发生。我已经成长为喜欢看他的Log WARN / INFO / ERROR Free的开发者。 ;)
所以,这是我自己的经历:
我收到了消息:
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服务(没有分页功能)通过将所有这些视图以正确的顺序添加到LinearLayout(在ScrollView中具有垂直方向),这些视图将充当行,子节标题和节标题。所有这些都是为了模拟带有可点击元素的listView ......但是,这是另一个问题。
作为一个负责任的开发人员,您希望使用系统资源使应用程序真正高效,因此列表的最佳实践(当您的列表不那么复杂时)是使用带有Loader的ListActivity或ListFragment并填充ListView一个适配器,这应该更高效,事实上它是,你应该一直这样做,再次...如果你的列表不是那么复杂。
解决方案:我在我的REST / JSON Web服务上实现了分页,以防止“大响应大小”,并且我在AsyncTask上包含了添加“rows”,“section headers”和“sub-section headers”视图的代码保持主线冷却。
所以...我希望我的经验可以帮助其他人用这条信息消息打开他们的头脑。
快乐的黑客攻击!
答案 3 :(得分:11)
这通常在使用模拟器进行调试时发生,而模拟器无论如何都是慢速的。
答案 4 :(得分:11)
在我的情况下,当我显示sherlock操作栏不确定进度条时,我有这些消息。由于它不是我的图书馆,我决定隐藏编舞者的作品。
您可以使用此过滤器表达式将Choreographer输出隐藏到Logcat视图中:
代码:^((?编导)。*)$ 强>
我使用了其他地方解释的正则表达式:Regular expression to match a line that doesn't contain a word?