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

RejectedExecutionException Error 질문드립니다!!

0 추천
@Override
    public void onBindViewHolder(ViewHolder holder, int position) {

        holder.setIsRecyclable(false);

        String checkFile = items.get(position).getMsg();
        String uri = checkFile.substring(checkFile.lastIndexOf(".") + 1, checkFile.length());

        Log.i("확장자", String.valueOf(uri));

        //items.get(position).getMsg().contains(uri)

        //holder.msg.setText(items.get(position).getMsg());

        Picasso.with(context).load(items.get(position).getUri()).resize(100, 100).into(holder.imageBitmapView);

        mHandler = new Handler();

        thread = new Thread(new Runnable() {
            @Override
            public void run() {

                mHandler.post(new Runnable() {
                    @Override
                    public void run() {

                        Log.i("thread", "run");

                        notifyDataSetChanged();

                    }
                });
            }
        });

        thread.start();
    }

W/System.err: java.util.concurrent.RejectedExecutionException: Task com.google.firebase.storage.zzb@b40328e rejected from java.util.concurrent.ThreadPoolExecutor@3c9de76[Running, pool size = 5, active threads = 5, queued tasks = 128, completed tasks = 261]
 

Adapter 클래스에서 picasso로 사진을 로드하고서 recyclerView에 notifyDataSetChanged 시켜주려 하는데,

위와 같이 작업 시 thread가 계속 계속 반복되어서 RejectedExecutionException 에러가 발생합니다 위 처럼요,

 

어떻게 하면 RejectedExecutionException 를 피하고 사진을 refresh 할 수 있을까요???

답변 부탁드립니다!!
알파고 (4,320 포인트) 님이 2017년 12월 13일 질문
로직상 무한루프 돌게 되어 있는데요.
그럼 어떻게 해줘야 할까요???
로직자체가 이상한데요.
notifyDataSetChanged()는 리스트 데이타 모델의 변경시에
변경사항을 반영해주는 메소드입니다.
데이터가 변경되지 않았음에도 왜 호출해주는 건가요?
위에 picasso로 이미지를 집어넣는데요 refresh하지 않으면이 이미지가 출력이 안됩니다. 예를 들면 picasso이후 다음 item이 추가되어야지만 이미지가 보여요. 그래서 thread안에 notifydatasetchanged 를 넣었는데 이런 에러가 뜨네요;;

그리고 왜 무한루프인지 간단하게 설명 부탁드립니다.
제가 잘 모르고 답변드렸네요.
리싸이클러뷰는 notifyDataSetChanged해도 해당 data가 같으면
onBindViewHolder를 호출하지 않으니
아이템 갯수만큼 처음 쓰레드가 생성되는 것 말고는 동작하지 않겠군요.

//RejectedExecutionException 오류는
http://sjava.net/tag/rejectedexecutionexception/
위의 링크를 보면 한번에 많은 쓰레드를 생성하기 때문인것 같으니
해당 쓰레드 실행코드를 제거하면 상단의 오류는 없어질 것 같습니다.

또한 Picasso의 이미지가 안나오는 이유는
해당 이미지 뷰의 width 와 height 값을 wrapcontent로 지정되어서
이미지가 다운받아지는 시점에 뷰가 그려지기 때문이 아닌가 합니다.
https://stackoverflow.com/questions/21889735/resize-image-to-full-width-and-variable-height-with-picasso

이미지가 가변이라면 이미지의 ratio 값을 구해서 리사이즈 및 placeholder 이미지를 적용해 주시면 될 것 같습니다.
일단 답변 정말 갑사드립니다!! 말씀하신대로 하던 중에

문제를 알았습니다; 제가 Firebase Storage를 이용하는데요, 위에 Picasso 코드 호출 시에

 try
        {
            pathReference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                @Override
                public void onSuccess(Uri uri) {
                    // Got the download URL for 'users/me/profile.png'
                    Log.i("File Download","Download Success");

                    getUri = uri.toString(); // <- 제 생각대로라면 여기에 값이 저장된 후,

                    Log.i("getUri", getUri);


                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception exception) {
                    // Handle any errors
                }
            });
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }

return getUri; // 저장된 값을 return; 하는게 목적이였는데,,

이런식으로 해서  내려받은 uri를 picasso에 넣어주는 작업을 하는건데,
 제 생각대로라면 Firebase 에서 Uri를 내려받는데에 성공하면
onSuccess() 메소드가 호출되고 그 뒤에 return getUri 함으로써 picasso에 넣어주고 이미지 출력인데,

이게 순서가 제 생각에 위에 Uri 내려받는 Firebase 코드가 Thread라서 별개로 움직이는 것 같아요,,;

지금 상황이
지금 상황이 Firebase 코드를 호출 후에 onSuccess 까지 기다리지 않고
값이 저장되어있지 않은 상태에서 그냥 return 해버립니다;;

당연히 전달받은 쪽에서는 null 값이 뜨구요;;

이렇게 전달 받은 후에 onSuccess가 작동되고, 이런 이유때문에 한번더 같은 작업을 했을 때에 뒤늦게 이미지가 표시됬던 것 같습니다.
그래서 지금 해결법을 찾고 있습니다 ,,ㅠㅠ 어쩌면 좋을지;;
아! 해결했습니다 !! 괜히 쓸데없이 코드를 짜놨던 것 같아요 , 답변 달아주시면 바로 채택하겠습니다. 감사합니다.

답변 달기

· 글에 소스 코드 보기 좋게 넣는 법
· 질문에 대해 추가적인 질문이나 의견이 있으면 답변이 아니라 댓글로 달아주시기 바랍니다.
표시할 이름 (옵션):
개인정보: 당신의 이메일은 이 알림을 보내는데만 사용됩니다.
스팸 차단 검사:
스팸 검사를 다시 받지 않으려면 로그인하거나 혹은 가입 하세요.
...