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

안녕하세요. 뷰 페이저 관련 쓰레드 알람?이 떠서 문의드립니다.

0 추천

안녕하세요.

제가 뷰 페이저 예제를 만들어서 작업중인데

The application may be doing too much work on its main thread.

이 문구가 자꾸 나와서요. 앱도 죽을때가 가끔 있고..

 

일단 상황은

앨범을 키고, 앨범을 키는 인텐트에 Intent.EXTRA_ALLOW_MULTIPLE을 true로 선언하여.. 여러 장을 선택할 수 있게 했습니다.

 

그리고 여러장을 선택하면, 뷰페이저가 있는 액티비티로 해당 앨범에서 가져온 사진들의 URI값을 리스트에 넣어 인텐트로 전달하게했구요.

 

뷰페이저에서는 받은 uri리스트를 풀어서, 뷰페이저에 띄우게 했거든요.

그런데 이 사진을 여러 장.. 특히 많이 가져올 경우 저 위에 문구가 나오더라구요. 메인쓰레드는 UI를 접근할 수 있다고 알고 있기 때문에, 일단 쓰레드나 그런건 잘 사용할줄모르지만.. Async를 상속받는 내장? 이너클래스를 써서 거기서 이미지 가져오고.. UI는 pre, post Execute에서 하게 했으나, 그래도 저 문구가 계속 나옵니다..

앱은 잘 안죽게 되긴 했지만.. 각 사진들 업로드하는 것도 그렇구요.. (업로드용 클래스도 Async로 만들었어요)

이럴땐 어디를 손봐야할까요??

 

 

 

**소스 :

onCreate()

priorList = getIntent().getStringArrayListExtra("list");

SetPage setPage = new SetPage();
setPage.execute();

SetPage 클래스

public class SetPage extends AsyncTask<Void, Void, Void> {
        public SetPage() {
        }

        @Override
        protected Void doInBackground(Void... params) {
            pagerAdapter = new PagerAdapter() {
                @Override
                public int getCount() {
                    return priorList.size();
                }

                @Override
                public Object instantiateItem(ViewGroup container, int position) {

                    View view=null;
                    view= getLayoutInflater().inflate(R.layout.childview, null);
                    ImageView img= (ImageView)view.findViewById(R.id.iv_childView);


                    BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inSampleSize = 4;
// highList : 원본
// lowList : 저화질(1/4)

                    Uri uri = Uri.parse(highList.get(position));
                    String path = uri.getPath();
                    Bitmap myBitmap = BitmapFactory.decodeFile(path, options);
                    lowList.add(path);
                    img.setImageBitmap(myBitmap);

                    container.addView(view);
                    return view;
                }

                @Override
                public void destroyItem(ViewGroup container, int position, Object object) {
                    // super.destroyItem(container, position, object);
                    container.removeView((View)object);
                }

                @Override
                public boolean isViewFromObject(View view, Object object) {
                    // return false;
                    return view==object;
                }
            };

            return null;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pager.setOffscreenPageLimit(priorList.size()-1);
            progressDialog = new ProgressDialog(ImagesView.this);
            progressDialog.setTitle("요기");
            progressDialog.setMessage("랍니다");
            progressDialog.setCancelable(false);
            progressDialog.show();

        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);

            pager.setAdapter(pagerAdapter);
            progressDialog.dismiss();
        }
    }
}

인터넷을 보니.. 이미지 크기를 줄이라고해서, 비트맵팩토리의 옵션에서 샘플사이즈를 1/4로 줄이기도 했고..

뷰페이저의 setOffscreenPageLimit도 보라고해서, 넘어온 이미지리스트의 사이즈-1 까지 만큼도 해서..

각페이지 전환은 매끄럽게 됐는데도 저 문구가 계속 나와요 ㅠㅜ 이러다 앱들 또 죽을것같기도하고

 

그리고.. 저 프로그레스 다이얼로그가 너무 빨리 동작해서 보이지 않는건지, onPre때 보이고 onPost때 끄는건데, onPost까지가 빨리오는 느낌이랄까.. 프로그레스 다이얼로그가 보이질 않는데 답은 없을까요..

 

업로드하는 클래스에서도 저렇게 다이얼로그 넣었는데 Toast로는 확인이 잘되는데, 다이얼로그는 나오질 않네요.

 

어쨌든 잘 아시는분 계시면 조언 부탁드립니다(__)

겸군님 (1,900 포인트) 님이 2017년 7월 19일 질문

1개의 답변

0 추천
 
채택된 답변
비트맵 디코딩을 메인스레드에서 하고 있습니다.
익명사용자 님이 2017년 7월 19일 답변
겸군님님이 2017년 7월 19일 채택됨
제가 잘못생각하고 있었네요~

Async를 전체적으로 쓰지 않고 instantiateItem()안에 async를 넣어서 처리했습니다.. 그 비트맵 디코딩을 UI에서 하게하고, 비트맵만 리턴받아 차일드뷰에 뿌리는건 Post에서 하도록..

감사합니다 :)

언제나 이 쓰레드랑 UI쪽은 머리는 이해가는데, 짜려고 하면 헛갈리네여
...