마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

[ContentProvider] 카톡은 어떻게 그렇게 빠르게 폰의 모든이미지 불러올 수 있을까요?

0 추천
[ContentProvider] 카톡은 어떻게 그렇게 빠르게 폰의 모든이미지 불러올 수 있을까요?

1000개정도 이미지가 폰에 저장되어 있는데.
contentProvider를 이용해서
제가 만들면 약 7초정도 걸리는데
카톡은 바로 뜹니다.

Activity띄우기전에 미리 불러오는건가 싶었는데
새로운 사진파일을 찍어도 바로 적용되는걸로 봐서
미리 불러오는 건 아닌거 같던데..

어떤 식으로 개발하면 그렇게 바로 뜰 수 있을까요?
목마른어린양 (960 포인트) 님이 2018년 5월 30일 질문

2개의 답변

0 추천
일반적으로 이런 경우에는 1000개의 이미지를 바로 로드하지 않고,

화면에 우선 보여줘야하는 일부 이미지와 스크롤시 바로 보여워야하는 일부만

우선 로드합니다.

그 다음 background에서 나머지 이미지를 로드하는 과정으로 진행됩니다.
디자이너정 (42,810 포인트) 님이 2018년 5월 30일 답변
말씀하신 부분은 recyclerview에서 image를 로딩할때 소요되는 시간에 대한 것 같습니다.

저는 recyclerAdapter에 data를 넘겨주기 전에
그 data를 cursor를 이용해서 받아오는 시간이 대략 7초정도 걸린다는 얘기였습니다.

답변 감사합니다 ^^

답변을 다시 수차례 읽어보니
recycler에 일부data만 보내고
나머지는 background로 처리한다는 것이..

어떤 식으로 하는 것인가요?
관련된 비슷한 로직이라도 링크로 알려주실 수 있으신지...?
0 추천
ContentResolver를 사용해서 MediaStore.Images.Media.EXTERNAL_CONTENT_URI 로 쿼리를 하시는거 맞나요? 1000개 정도면. 0.5초도 안 걸리고.. 결과를 가져올 것 같네요.. 그리고 썸네일도 비슷한 방식으로 이미 만들어져 있는 것을 불러오면 됩니다.
mcsong (44,040 포인트) 님이 2018년 5월 31일 답변
넵.

        String[] projection = {MediaStore.Images.Media.DATA};

        Cursor cursor = getContentResolver().query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                projection,
                null,       
                null,
                MediaStore.MediaColumns.DATE_ADDED + " DESC");      

...
...cursor로 받은 데이터 정리하는 부분
...


원래는 0.5초도 안 걸리나봐요...?
로직이 긴 것도 아니라서
제가 뭘 잘못 했는지 뒤져볼 로직도 없네요..

혹시
다른 방식으로 images를 불러오는 api가 있나요?

답변 감사합니다. ^^
selection 이 없어서.. 느린가 봅니다. selection을 넣어 줘 보세요. ^^
문제되는 부분을 찾았습니다.
cursor로 받은 image에서 thumbnail이 없을때
thumbnail을 만들어주는 부분에서 delay가 생기는 것 같습니다.

이상한 점은
String[] projection = {MediaStore.Images.Thumbnails.DATA};

이 projection으로 모든 thumbnail을 받아오면
150여개 밖에 안 됩니다.(전체 이미지는 1000개인데.)
왜 thumb이 저거밖에 없는건가요?

thumb을 받아오는 다른 로직이 있나요?

감사합니다.
MediaStore.Images.Thumbnails.getThumbnail() 메서드로 받아오시면 됩니다. 거의 있던데.. 만약 없으면.. DATA 필드에서 썸네일을 만드셔서 캐시하셔서 사용하시면 됩니다..
넵. 그렇게 해놓았습니다.

MediaStore.Images.Thumbnails.getThumbnail(getContentResolver(),
                    Long.parseLong(imageId),
                    MediaStore.Images.Thumbnails.MINI_KIND,
                    null);
            
그런데 여기서 delay가 너무 많이 됩니다.
thumb이 없는 image가 800여개라서 그런것 같습니다.
근데 카톡은 어떻게 한건지.. 연구를 좀 해봐야 겠습니다.

'DATA 필드에서 썸네일을 만드셔서 캐시하셔서 사용하시면 됩니다'
캐시한다는 게 정확히 이해가 안 됩니다.
Thumb을 Bitmap으로 만들어서 사용하라는 말씀이신거 같은데..? 맞나요?
혹시.. Thumbnail 처리를 같은 스레드에서 불러오는건 아닌 거죠? 보통 Thumbnail 을 가져와서 imageview에 바인딩할 때는 다른 스레드를 사용합니다.
네. 메인스레드로만.. 그러고 있었습니다...ㅠㅠ

오늘 코딩 결과는
Thumbnail을
Adapter내의 onBindViewHolder에서
그때그때 받아오는 걸로 짜놓으니 delay가 없이 한번에 잘 뜹니다.

단, 스크롤을 한번에 확 내리면 버버버벅 대기는 하지만..
MainThread를 덜 이용하게끔 코드수정을 해야 할 것 같습니다.


Thread에 대해 하나만 더 질문 드려도 될까요?

Adapter내의 onBindViewHolder에서
각각의 item에 대한 처리를 Asynctask로 만들어도 될까요?
(item이 1000개면 1000개의 1회용 Thread가 만들어지는거죠.)

이런식으로 짜는게
퍼포먼스에 도움이 되나요?


한마디씩 답변해 주신 말씀들이 도움이 많이 됐습니다.
감사합니다. ^^
네.. 그런식으로 만들어야 합니다..

제가 기존 AsyncTask가 가지고 있는 문제(요청이 너무 많으면 크래시 발생)나 이전 버전의 안드로이드에서 성능 저하 이슈를 해결한 라이브러리를 개발한게 있는데요.. 아래 라이브러리 참고해 보세요..

https://github.com/mcsong/AdvancedAsyncTask

그리고, 도움이 되셨으면.. 제가 개발한 앱인데. 아무거나 별점 좀 부탁드리겟습니다.
https://play.google.com/store/apps/details?id=net.sjava.file
https://play.google.com/store/apps/details?id=net.sjava.docs

감사합니다. ^^
네. 다운받고 후기 남겼습니다.
혼자서 이런 어플을 만드시다니 정말 대단하십니다!!
다음에도 시간되시면 답변 부탁드려요^^
감사합니다.
ㅎㅎ 답변이 도움이 되었다니 다행이네요..
별점 정말 감사합니다. ^^
...