안녕하세요?
이것이 저한테만 도움이 되는진 잘몰르겠지만.. 저와같은 상황에 직면하신분이 계실까봐서 이렇게 글을 올립니다.
베이스 & 배열 어댑터 모두 getView가 핵심이잖아요?
일단 아래의 그림을 봐주세요.
1.드래그시 아이템이 랜덤으로 변경돼는 문제가 있는 소스코드..
2. 해결됀 소스코드
이것하나때문에 어제밤부터 지금까지 코드하나하나 문제점찾느라 시간이 너무많이 소비됬습니다.
익셉션이라도 일어나는 상황이었으면 금방찾았을건데..
저도 자바 깊게 공부하진 못했지만.. 솔직히 위,아래 그림이 파라미터변수 지역변수 등등의 범위 관련문제와 엮인것인지..
아니면 알수없는 버그인지.. 판단을 못하겠습니다. 아무튼 이런방식으로도 해결이 가능하다는걸 참고하시라고..
저녘식사 맛나게드십시요..
BaseAdapter에서는 HolderPattern을 사용해야 합니다.
이전 뷰를 사용하기 위해서 convertView를 쓰는데요.. 그럴필요 없이 생성자쪽에서
배열로 담아 두었다가 한번에 로딩하고 순서에 맞게 꺼내 쓰는게 HolderPattern의 핵심입니다.
하지만 HolderPattern에서도 문제가 발생됩니다. 바로 개체수가 많을때인데요.. 만약 1000개의 raw를 가지고 있다면
1000개를 배열에 한번에 로딩하고 꺼내 쓰려면 메모리 소비가 장난아니고 종종 메모리 부족으로 로딩하다
죽을수도 있을겁니다.
그래서 동적 로딩을 해야 하는데요..
보여지는 화면의 개체수만큼 가지고 있고 나머진 메모리상에서 로딩했다 지웠다 하면서 사용하는거랍니다.
그게 cache 방법이고 , 흔한 캐쉬 방법중에 LRU Cache를 쓰는데 리스트에서는 문제가 발생됩니다.
그래서 Double Checked 방식으로 Double Linked List LRU로 구현도 한답니다.
http://tyche87.tistory.com/m/post/view/id/99
아즈라엘님 친절한 답변, 그리고 도움을주셔서 감사드립니다.
위에 두분... 리플보고...
진짜 이렇게 공개됀 장소에서 기분이 더럽게 느껴지는건 처음느껴보네요..
두분 성정이 어떤지 딱 알겠네요.. 차라리 어디부분을 중점으로 기초를 다시 닦으라고 말씀을해주시고 지적하셨으면
무지함을 반성하면서 더 감사했을건데..
초보에게 나은방향을 제시해주시는 아즈라엘님을 보면 정말 이런분들이 계셔서 인생에 도움이되는구나.. 라고 절실하게 느껴지는반면..
제가지금 쓴글때문에 탈퇴당해도 할말은없지만서도..
제글에는 리플도 관심도 같지마시고 그냥 지나쳐주세요... 그리고 글올리실때 글쓴이의 심정도 생각하고 글을 쓰세요..진짜..
누가보면 가치없는정보라도 저에겐 고생해서 얻은결론인데 그래서 혹시 도움이 될까하여 올린것뿐인데..
오늘밤은진짜 잠이 잘안오겠네요...
여긴 열려있는 공간이고 이곳에 글을 올리시는것은 댓글도 받을 수 있다는 전제로 글을 다시는것 아닌가요?
특히 안펍은 안드로이드 내놓으라 하는 고수들이 많은 곳인데
그곳의 앱개발 노하우라고 올려놓는게 책이나 하다못해 구글에서 검색 한번 안해본듯한
글에대해 소감을 밝혔을 뿐입니다. 아예 말머리에 초보용 이라던가 등등의 말머리라도 있었으면 모를까..
1. 아답터는 철저히 구글에서 MVC 모델을 기초로 만든 것입니다. (이건 구글 개발자 문서에 기록된 사항입니다.)
아답터의 소스에 try-catch 같은 형태의 구문이 있는 것은 문제가 있는 방법입니다.
아답터에 데이터를 바인딩 하기 전에 데이터에 대한 신뢰성 검출이 먼저입니다.
2. 아답터를 잘 활용하면 리스트뷰의 필터링 기능에도 이용가능합니다.
가급적이면 getItem 같은 다양한 내부 메쏘드를 오버라이드 해서 활용하시기 바랍니다.
리스트 대상에 직접적으로 접근하여 list.get(index) 같이 구현하는 것은 유지보수성이 매우 떨어집니다.
3. 바인딩 대상에 비트맵이 있는 것 또한 문제가 있습니다.
가급적이면 이미지는 파일로 저장 한 후 필요한 경우에만 BitmapFactory 의 메쏘드로 처리 한 후
비사용시 recycle 처리를 해주세요.
구글은 매우매우 훌륭한 학교이며 StackOverFlow 는 최고의 선생님들이 모인 곳이죠.
사실 전 필요한 데이터들은 안드로이드펍에서는 안 구해요.
SOF 에서 구하는게 100배는 더 빠르니깐요 :)
초급에게 어려운 이슈들은 커니님 같은 좋은 강사님의 블로그에서도 많이 구할 수 있고요
저도 잎사귀님처럼 구현을 했었습니다.
그런데 저것도 버그가 있는지 제가 못하는건지,
저 같은 경우는 동적으로 리스트뷰 row에 각각 버튼이 있어 클릭을 하면
특정 row의 값을 A => B로 변경 해야 했는데요.
예를들어 position 0의 A값을 B로 변경하고
뒤로 갔다 다시 들어오면
당연히 position 0의 값이 B로 되어 있지만
위에서 B로 변경했을때 안보였던 view들의 값이
같이 변하는 버그가 있더군요. -_-; 제가 못하는걸수도 있는데
계속 리스트뷰를 드래그 하면 다시 잘 나왔다가
다시 또 드래그 하면 값이 변경되게 나왔다가 그러더군요,
물론 log를 찍어보면 데이터 값들은 잘 나옵니다.
저 같은경우는 무식하지만 convertview를 조건걸지 않고
무조건 새로 뿌려주는 방식으로 해결했었습니다.
음.. 너무 당연한걸 써 놓으시니 어떻게 반응을 해야 할지 모르겠습니다.. ㅡ.ㅡ;
버그도 아니고.. 원래 이런것이고.. 딱 하나 알겠는건 아래 올리신 httpclient 글과 엮어서 생각해보건데
잎사귀님이 프로그래머 초보시거나 아직 감을 못잡고 계시다는것 정도..
공부도 부족하시구요..