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
sで行われているため、私のアプリケーションがどのような "やり過ぎる"作業を行っているのかを判断する方法を知る必要があります。
Choreographerを使用すると、アプリでvsyncに接続し、適切なタイミングでパフォーマンスを向上させることができます。
Androidのビューアニメーションは、内部的に同じ目的でChoreographerを使用します。アニメーションのタイミングを適切に設定し、パフォーマンスを向上させるためです。
Choreographerはすべてのvsyncイベントについて通知されるので、Choreographer.post * apisによって渡されたRunnablesの1つが1フレームの時間内に完了しないためにフレームがスキップされるのかどうかを判断できます。
私の理解では、Choreographerはフレームスキップを検出することしかできません。なぜこれが起こるのかを知る方法はありません。
メッセージ「アプリケーションはメインスレッドで作業しすぎている可能性があります」誤解を招く可能性があります。
私はパーティーに遅れています、しかしうまくいけばこれはここに他の答えへの役に立つ追加です...
私の処理はすべてAsyncTasksで行われているので、私はどのようにして私のアプリケーションが何をしているのかを判断する必要があります。
以下はすべて候補です。
Uri
name__の設定ImageView
name__はすべてメインスレッドのIOを構成します)View
name__階層のレンダリングView
name__階層の大部分を無効にするonDraw
name__内の高価なView
name__メソッドAsyncTask
name__はデフォルトで "background"です。Java.lang.Thread
はnot)特定の原因を実際に判断するには、アプリケーションのプロファイルを作成する必要があります。
私は試して、 code を見て、Choreographerを理解しようとしています。
Choreographerのドキュメンテーションは、「アニメーション、入力、および描画のタイミングを調整する」で始まります。これは実際には良い説明ですが、残りはアニメーションを強調しすぎます。
Choreographerは、実際には次の順序で実行される3種類のコールバックを実行する責任があります。
目的は無効化されたビューが再描画される(そしてアニメーションがトゥイーンされる)レートをスクリーンのvsync(通常は60fps)に合わせることです。
スキップされたフレームに関する警告は後付けのように見えます:singleが3つのステップを通過するときにメッセージが記録されるのは予想されるフレーム期間の30倍以上です。ログメッセージに「スキップされた30frames」と表示されることがあります。eachpassの場合、30フレームスキップする必要がある場合よりも50%長くなります(いたずら!)それについて警告されません。
3つのステップから、警告を引き起こすことができるのはアニメーションだけではないことが明らかになりました。複雑なonDrawメソッドを使用して、大規模なView
name__階層またはView
name__の大部分を無効にすることで十分です。
例えばこれは繰り返し警告を引き起こします:
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
name__の間のスタックから、あなたがアニメ化しているかどうかにかかわらず、振付家が関与していることがわかります。
example.AnnoyTheChoreographerActivity $ 1.onDraw(AnnoyTheChoreographerActivity.Java:25)にAndroid.view.View.draw(View.Java:13759)
...かなりの繰り返し...
android.widgetのAndroid.view.ViewGroup.drawChild(ViewGroup.Java:3169)でAndroid.view.ViewGroup.dispatchDraw(ViewGroup.Java:3039)でAndroid.view.View.draw(View.Java:13762)で。 Androidの場合はcom.Android.internal.policy.impl.PhoneWindowの$ DecorView.draw(PhoneWindow.Java:2396)の場合はFrameLayout.draw(FrameLayout.Java:467)が表示されます。 Android.viewでのAndroid.view.HardwareRenderer $ GlRenderer.draw(HardwareRenderer.Java:1144)でのview.View.getDisplayList(View.Java:12754)。 Android.view.ViewRootImpl.doTraversal(ViewRootImpl.Java:1112)でのAndroid.view.ViewRootImpl $ Trar.RunでのViewRootImpl.performDraw(ViewRootImpl.Java:2145) (ViewRootImpl.Java:4472)Android.view.Choreographer $ CallbackRecord.run(Choreographer.Java:725)at Android.view.Choreographer.doCallbacks(Choreographer.Java:555) .view.Choreographer.do Frame(Choreographer.Java:525)at Android.view.Choreographer $ FrameDisplayEventReceiver.run(Choreographer.Java:711)at Android.os.Handler.handleCallback(Handler.Java:615)at Android.os.Landper.dispatchMessage(Handler.Java:92)at Android.os.Looper.loop(Looper.Java:137)at Android.app.ActivityThread.main(ActivityThread.Java:4898)
最後に、メインスレッドが処理できる作業量を減らす他のスレッドとの競合がある場合、実際にメインスレッドで作業をしていなくても、フレームをスキップする可能性が劇的に高まります。
この状況では、アプリケーションがメインスレッドでやり過ぎていることを示唆するのは誤解を招くと考えられるかもしれませんが、 Androidはメインスレッドを飢えさせないようにするためにワーカースレッドの優先順位を低くしたい 。ワーカースレッドの優先順位が低い場合、Choreographerの警告を表示する唯一の方法は、メインスレッドでやり過ぎることです。
これはInfoメッセージが多くの状況であなたのLogCatに現れる可能性がある場合です。
私の場合は、プログラムでXMLレイアウトファイルから複数のビューを展開していたときに起こりました。メッセージ自体は無害ですが、後からAppが使用できるRAMすべてが使用され、巨大なForce Closeが発生するという問題が発生している可能性があります。私は彼の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をシミュレートするためのすべてのこと...しかし、それは別の質問です。
責任ある開発者として、システムリソースを使ってアプリを本当に効率的にしたいので、リストのベストプラクティスは(リストがそれほど複雑ではない場合)、ListActivityまたはListFragmentをLoaderで使用し、ListViewをアダプタで埋めることです。これはおそらくもっと効率的です、実際それはそうです、そしてあなたはいつもそれをやるべきです…あなたのリストがそれほど複雑でないならば。
解決策:私は自分のREST/JSON Webサービスにページングを実装して「大きなレスポンスサイズ」を防ぎ、メインを維持するためにAsyncTaskに「rows」、「section headers」および「sub-section headers」ビューを追加したコードをラップしました。クールスレッド。
だから...私の経験が、このInfoメッセージで頭を割っている他の誰かに役立つことを願っています。
ハッピーハッキング!
私の場合は、シャーロックのアクションバーを表示しているときにこれらのメッセージが表示されます。私のライブラリではないので、私はChoreographerの出力を隠すことにしました。
このフィルター式を使用して、Choreographerの出力をLogcatビューに隠すことができます。
タグ:^((?! Choreographer)。*)$
私は他の場所で説明された正規表現を使いました: 単語を含まない行にマッチするための正規表現?
これは通常、エミュレータを使用してデバッグするときに発生します。エミュレータはとにかく遅いことが知られています。