본문

[2017.09.19] 09. 리스트 뷰 원리 및 성능 향상

리스트 뷰의 원리

리스트 뷰의 원리는 그림과 같이 Data가 Adapter에 등록된 후 Adapter를 통해 ListView에 출력된다. 

(리스트 뷰의 개념 - http://heepie.tistory.com/76)

여기서 주목 할 점은 Adapter를 통해 화면에서 사라진 리스트는 다음으로 보여질 리스트로 View가 재활용된다는 것이다. 

이렇게 View가 재활용된다는 것에 착안해 리스트 뷰의 성능을 향상 시키는 방법을 알아보자.


문제점1. 끊임없는 객체로드 - 메모리 과부하

(움짤을 계속보면 눈 아파서 접어놨다.)


해결책1. View 내부의 값만 변경해 재활용

View 새로 생성해 재활용

View 내부 값만 변경해 재활용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Override
public View getView
(int position, View view, ViewGroup vg)
{
    // xml을 메모리에 로드한다.
    view = LayoutInflater
            .from(context)
            .inflate(R.layout.item, null);
 
    // 해당 xml에 정의한 TextView를 객체화
    TextView textResult 
        = (TextView)view
            .findViewById(R.id.textResult);
 
    // TextView에 데이터 출력
    textResult.setText(data.get(position));
 
    return view;
}
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Override
public View getView
(int position, View view, ViewGroup vg)
{
 
    if(view == null) {
        // xml을 메모리에 로드한다.
        view = LayoutInflater
                .from(context)
                .inflate(R.layout.item, null);
    }
 
    // 해당 xml에 정의한 TextView를 객체화
    TextView textResult 
            = (TextView)view
                .findViewById(R.id.textResult);
 
    // TextView에 데이터 출력
    textResult.setText(data.get(position));
 
    return view;
}
cs


모바일로 문제점 해결 전 후로 App을 실행해 보았을 때 버벅거림이 사라진 것같다... 정말 미세하게 느껴져서 못 느낄 수도 있을 것 같다.


문제점2. 끊임없는 변수, 리스너 등의 선언

위와 같이 개선을 했음에도 불구하고 getView 메소드가 실행 될 때마다 TextView 변수를 선언하고 객체화한다. TextView 변수 하나 설정하는 것이 무슨 문제냐고 말할 수 있지만 리스트 뷰 안에 많은 객체가 들어 갈 수로 더욱 많은 변수를 선언해야 한다. 

1
2
3
4
5
6
7
8
9
@Override
public View getView(int position, View view, ViewGroup viewGroup) {
    // ...
 
    TextView textResult = (TextView)view.findViewById(R.id.textResult);
 
    // ...
    return ret;
}
cs


해결책2. Holder 클래스와 Tag 사용해 변수 재활용

호출될 때마다 변수 선언

Holder 클래스와 Tag 사용해 변수 재활용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Override
public View getView
(int position, View view, ViewGroup vg)
{
 
    if(view == null) {
        // xml을 메모리에 로드한다.
        view = LayoutInflater
                .from(context)
                .inflate(R.layout.item, null);
    }
 
    // 해당 xml에 정의한 TextView를 객체화
    TextView textResult 
            = (TextView)view
                .findViewById(R.id.textResult);
 
    // TextView에 데이터 출력
    textResult.setText(data.get(position));
 
    return view;
}
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Override
public View getView
(int position, View view, ViewGroup vg)
{
    Holder holder;
 
    if(view == null) {
        // xml을 메모리에 로드한다.
        view = LayoutInflater
            .from(context)
            .inflate(R.layout.item, null);
 
        // holder 인스턴스 생성
        holder = new Holder(view);
 
        // view에 holder 셋팅
        view.setTag(holder);
    } else {
        // view가 존재하면 holder 셋팅
        holder = (Holder)view.getTag();
    }
 
    // TextView에 데이터 출력
    holder.getTextView()
            .setText(data.get(position));
 
    return view;
}
cs


Holder 클래스


정리



#리스트 뷰 #리스트 뷰 성능 향상 #리스트 뷰 원리 #리스트 뷰 최적화 #리스트 뷰 문제 #리스트뷰

공유

댓글