Logcat에서 안무가 메시지의 의미
- 응용 프로그램의 주 스레드에서 너무 많은 일을 할 수있다 (15) 답변
최신 버전을 설치하고
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에 의해 전달 된 Runnable 중 하나가 한 프레임 시간 내에 완료되지 않아 프레임을 건너 뛸 수 있는지 알 수 있습니다.내 이해에서 Choreographer는 프레임 건너 뛰기 만 감지 할 수 있습니다. 왜 이런 일이 발생했는지 말할 방법이 없습니다."응용 프로그램이 기본 스레드에서 너무 많은 작업을 수행하고있을 수 있습니다." 오해의 소지가 있습니다.
나는 파티에 늦었지만 여기에 다른 답변에 유용한 추가 정보가 있기를 바랍니다.
질문에 대답하기 / tl : dr;
모든 처리가 AsyncTasks에서 수행됨에 따라 애플리케이션이 "너무 많은 작업"을 수행하는지 확인할 수있는 방법을 알아야합니다.
다음은 모두 후보입니다.
- IO 또는 메인 쓰레드 비싼 처리 (드로어 블로드, 레이아웃을 팽창 및 설정
Uri
'에 s의ImageView
모든 메인 스레드 IO를 구성 s'의) - 대규모 / 복잡한 / 깊은
View
계층 구조 렌더링 View
계층 구조의 상당 부분 무효화onDraw
사용자 정의View
의 비싼 방법- 애니메이션에서 비싼 계산
- "작업자"스레드를 너무 높은 우선 순위로 실행하여 "배경"으로 간주 할 수 없음 (
AsyncTask
기본적으로 "배경"java.lang.Thread
은 아닙니다 ) - 가비지 컬렉터가 많은 스레드를 생성하여 메인 스레드를 포함한 "세상을 중지"시키는 원인
구체적인 원인을
파악
하려면 앱을 프로파일 링해야합니다.
자세한 세부 사항
나는
실험하고 살펴봄으로써 안무가를 이해하려고 노력했다 .Choreographer의 문서는 "애니메이션, 입력 및 드로잉 타이밍 조정"으로 열립니다. 실제로 좋은 설명이지만 나머지는 애니메이션을 지나치게 강조합니다.Choreographer는 실제로 다음 순서로 실행되는 3 가지 유형의 콜백을 실행합니다.
- 입력 처리 콜백 (터치 이벤트와 같은 사용자 입력 처리)
- 프레임 간 트위닝을위한 애니메이션 콜백으로, 실행중인 모든 / 모든 애니메이션에 안정적인 프레임 시작 시간을 제공합니다. 이 콜백을 두 번째로 실행한다는 것은 애니메이션 관련 계산 (예 : 뷰 위치 변경)이 세 번째 콜백 유형이 호출 될 때 이미 수행되었음을 의미합니다.
- 뷰 계층을 그리기위한 순회 콜백보기
목표는 무효화 된보기가 화면 vsync (일반적으로 60fps)로 다시 그려지는 속도 (및 애니메이션 트위닝)를 일치시키는 것입니다.건너 뛴 프레임에 대한 경고는 다음과 같습니다 . 3 단계를 통한
단일
패스가 예상 프레임 지속 시간의 30 배를 초과하면 로그 메시지에서 볼 수있는 가장 작은 숫자가 "
30
프레임 스킵"된 경우 메시지가 기록 됩니다. ; 경우
각
패스는 여전히 30 프레임 (건너 뛸 것보다 더 긴 50 %를 소요
장난 꾸러기!를
)하지만 당신은 그것에 대해 경고하지 않습니다.상당히 큰 부분 무효화 : 3 단계는 경고를 트리거 할 수 있습니다뿐만 아니라 애니메이션이라고는 명확 참여에서
View
계층 구조 또는
View
충분 수도있는 복잡한 된 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.
You can see from the stack during onDraw
that the choreographer is involved regardless of whether you are animating:
at example.AnnoyTheChoreographerActivity$1.onDraw(AnnoyTheChoreographerActivity.java:25) at android.view.View.draw(View.java:13759)
... quite a bit of repetition ...
at android.view.ViewGroup.drawChild(ViewGroup.java:3169) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3039) at android.view.View.draw(View.java:13762) at android.widget.FrameLayout.draw(FrameLayout.java:467) at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2396) at android.view.View.getDisplayList(View.java:12710) at android.view.View.getDisplayList(View.java:12754) at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:1144) at android.view.ViewRootImpl.draw(ViewRootImpl.java:2273) at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2145) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1956) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1112) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4472) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725) at android.view.Choreographer.doCallbacks(Choreographer.java:555) at android.view.Choreographer.doFrame(Choreographer.java:525) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711) at android.os.Handler.handleCallback(Handler.java:615) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4898)
Finally, if there is contention from other threads that reduce the amount of work the main thread can get done, the chance of skipping frames increases dramatically even though you aren't actually doing the work on the main thread.
In this situation it might be considered misleading to suggest that the app is doing too much on the main thread, but Android really wants worker threads to run at low priority so that they are prevented from starving the main thread. If your worker threads are low priority the only way to trigger the Choreographer warning really is to do too much on the main thread.
This if an Info message that could pop in your LogCat on many situations.
In my case, it happened when I was inflating several views from XML layout files programmatically. The message is harmless by itself, but could be the sign of a later problem that would use all the RAM your App is allowed to use and cause the mega-evil Force Close to happen. I have grown to be the kind of Developer that likes to see his Log WARN/INFO/ERROR Free. ;)
So, this is my own experience:
I got the message:
10-09 01:25:08.373: I/Choreographer(11134): Skipped XXX frames! The application may be doing too much work on its main thread.
... when I was creating my own custom "super-complex multi-section list" by inflating a view from XML and populating its fields (images, text, etc...) with the data coming from the response of a REST/JSON web service (without paging capabilities) this views would act as rows, sub-section headers and section headers by adding all of them in the correct order to a LinearLayout (with vertical orientation inside a ScrollView). All of that to simulate a listView with clickable elements... but well, that's for another question.
As a responsible Developer you want to make the App really efficient with the system resources, so the best practice for lists (when your lists are not so complex) is to use a ListActivity or ListFragment with a Loader and fill the ListView with an Adapter, this is supposedly more efficient, in fact it is and you should do it all the time, again... if your list is not so complex.
Solution: I implemented paging on my REST/JSON web service to prevent "big response sizes" and I wrapped the code that added the "rows", "section headers" and "sub-section headers" views on an AsyncTask to keep the Main Thread cool.
So... I hope my experience helps someone else that is cracking their heads open with this Info message.
Happy hacking!
This usually happens when debugging using the emulator, which is known to be slow anyway.
In my case I have these messages when I show the sherlock action bar inderterminate progressbar. Since its not my library, I decided to hide the Choreographer outputs.
You can hide the Choreographer outputs onto the Logcat view, using this filter expression :
tag:^((?!Choreographer).*)$
I used a regex explained elsewhere : Regular expression to match a line that doesn't contain a word?
참고URL : https://stackoverflow.com/questions/11266535/meaning-of-choreographer-messages-in-logcat
'Programming' 카테고리의 다른 글
흰색 위에 RGB를 RGBA로 변환 (0) | 2020.05.11 |
---|---|
장고 :“프로젝트”대“앱” (0) | 2020.05.11 |
기존 스키마에서 테이블 관계 다이어그램 생성 (SQL Server) (0) | 2020.05.11 |
is_a와 instanceof의 차이점은 무엇입니까? (0) | 2020.05.11 |
기존 배포 인증서를 해지하면 기존 앱에 문제가 있습니까? (0) | 2020.05.11 |