Android ViewTreeObserver

안드로이드에서 뷰는 메인쓰레드에서 그려지게 되는데, 간혹 뷰의 높이나 넓이를 알고 싶은데 그려지고 있는 시점에 확인하게 되면 값이 들어 오지 않는 경우가 있다. 그래서 뷰가 메인쓰레드에서 정상적으로 생성이 완료되는 시점을 알아야 하는 경우가 있다.

모든 뷰에는 ViewTreeObserver가 있으며 getViewTreeObserver()를 통해서 얻어 올 수 있다. 여기에 뷰와 관련된 interface를 제공하여 뷰의 상태를 전달 받을 수 있다. 주요 Listener는 다음과 같다. 

  • OnGlobalFocusChangeListener – 뷰의 포커스 변경시 호출
  • OnGlobalLayoutListener – 뷰의 변경이 생기면 호출
  • OnPreDrawListener – 뷰가 그려지기전 호출
이중에 OnGlobalLayoutListener를 이용하면 뷰가 그려진 후의 시점을 알 수 있다. 코드는 다음과 같다. 
private View mView;

private OnGlobalLayoutListener mGlobalLayoutListener = new OnGlobalLayoutListener() {
    public void onGlobalLayout() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            mView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        } else {
            mView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        }
        
        //TODO mView의 높이를 구하는 등의 작업.

    }
};

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    mView.getViewTreeObserver().addOnGlobalLayoutListener(mGlobalLayoutListener)
}

addOnGlobalLayoutListener는 한번 사용한 후 반드시 삭제를 해야한다. 뷰의 변경이 생기면 또 호출 되게 기때문에 한번 Callback된 후의 시점을 알고 난 후에는 Listener를 삭제하면 된다. 

삭제 하는 메서드는 젤리빈이후로 이름이 변경되여 다음과 같이 버전별로 처리 해야한다. 

Droid Inspector를 이용한 Android View구조 분석.

안드로이드의 앱의 퀄리티가 날이 갈 수록 높아지고 있는 만큼 이런 퀄리티 높은만큼 뷰의 구조가 점점더 복잡해지고 있다. 뷰의 구조가 복잡 할 수록 앱이 실행하는데 그 만큼의 영향을 미치게되어 사용자로하여 느린 반응을 보일 수가 있다. 이런 뷰의 구조를 최대한 줄이기 위해 최대한 노력해야 한다. ADT에서 훌륭한 Hierarchy Viewer를 통해 View의 구조를 도면같이 펼쳐서 보여주는 툴이 있다. 하지만 구조가 복잡하면 복잡해질 수록 보기에는 다소 무리가 있는 경험들이 있을 것이다.

이런 구조를 좀더 쉽게 파악할 수 있도록 3D로 표현 해주는 Droid Inspector이라는 툴을 하나 소개할까 한다.

Droid Inspect의 장점

– 3D로 View구조를 파악 할 수 있다.

– Overdraw를 찾아 낸다.

– 개별 View의 bounds를 볼 수 있다.

– DDMS plugin으로 지원 한다..

– View 계층을 숨기거나 보일수 있다.

– Web 파일로 추출 가능하다.


샘플 View 보기

설치 / 사용법

= 분석을 하기 위한 코드에서 메소드 호출 하기

1. 분석할 앱 프로젝트에 droidinspectorserver.jar 라이브러리에 import한다.

2. AndroidManifest.xml에 android.permission,INTERNET 퍼미션을 추가한다.

3. 화면이 그려지는 처음 시점과 끝 시점에 해당된 메소드를 호출 하도록 한다.

 import com.sriramramani.droid.inspector.server.ViewServer;

 public class MyActivity extends Activity {

     @Override
     public void onCreate(Bundle ofJoy) {
         super.onCreate(ofJoy);
         ViewServer.get(this).addWindow(this);
     }

     @Override
     public void onDestroy() {
         super.onDestroy();
         ViewServer.get(this).removeWindow(this);
     }

     @Override
     public void onResume() {
         super.onResume();
         ViewServer.get(this).setFocusedWindow(this);
     }
 }

= 분석된 View 구조 보기

  • Eclipse Plugin으로 구조를 보기

위에서 프로젝트를 실행 하고 분석할 해당화면으로 이동 후 아래 2가지 방식으로 구조를 볼 수 있다.

Plugin Url: http://www.sriramramani.com/droidinspector/eclipse/

플러그인 설치 후 DDMS화면에서 Droid Inspector 실행. 

  • Web browser로 구조 내보내기

1. droidinspectorclient.jar 라이브러리를 다운 받는다.

  1. console에서 다음고 같은 명령을 실행한다. 

$ adb forward tcp:5555 tcp:5555

$ java -jar droidinspectorclient.jar

  1. 명령 실행후 droid-inspector.html 파일이 생성되는데 열어 보면 된다.

Droid Inspector를 이용해서 필요 없는 뷰를 파악 / 구조를 단순하게 하여 조금이나마 성능을 개선 해보자.