user3509091
user3509091

Reputation:

Why does the image doesn't set in an Imageview using an Asynchronous Task?

I am trying to retrieve Facebook profile pic using a url and a Asynchronous Task. I am using the following code and I have posted the error log. Please tell me what is going wrong.

Mainactivty.class:

 final ImageView myImageView=(ImageView)findViewById(R.id.imageView1);
    AsyncTask<Void, Void, Bitmap> t = new AsyncTask<Void, Void, Bitmap>(){
        protected Bitmap doInBackground(Void... p) {
            Bitmap bm = null;
            try {
                URL aURL = new URL("https://graph.facebook.com/myfacebookid/picture?type=small");
                URLConnection conn = aURL.openConnection();
                conn.setUseCaches(true);
                conn.connect(); 
                InputStream is = conn.getInputStream(); 
                BufferedInputStream bis = new BufferedInputStream(is); 
                bm = BitmapFactory.decodeStream(bis);
                bis.close(); 
                is.close();
                //Bitmap bitmap =;
                Bitmap circleBitmap = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), Bitmap.Config.ARGB_8888);

                BitmapShader shader = new BitmapShader (bm,  TileMode.CLAMP, TileMode.CLAMP);
                Paint paint = new Paint();
                        paint.setShader(shader);

                Canvas c = new Canvas(circleBitmap);
                c.drawCircle(bm.getWidth()/2, bm.getHeight()/2, bm.getWidth()/2, paint);
                myImageView.setImageBitmap(circleBitmap);

            } catch (IOException e) { 
                e.printStackTrace(); 
            }
            return bm;
        }


    };
    t.execute();

Error log:

 04-11 09:23:25.849: E/AndroidRuntime(8640): FATAL EXCEPTION: AsyncTask #1
 04-11 09:23:25.849: E/AndroidRuntime(8640): java.lang.RuntimeException: An error occured while executing doInBackground()
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at java.lang.Thread.run(Thread.java:856)
 04-11 09:23:25.849: E/AndroidRuntime(8640): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:5073)
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:976)
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at android.view.View.requestLayout(View.java:15328)
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at android.view.View.requestLayout(View.java:15328)
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at android.view.View.requestLayout(View.java:15328)
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at android.view.View.requestLayout(View.java:15328)
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:292)
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at android.view.View.requestLayout(View.java:15328)
  04-11 09:23:25.849: E/AndroidRuntime(8640):   at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:292)
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at android.view.View.requestLayout(View.java:15328)
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at android.widget.ImageView.setImageDrawable(ImageView.java:413)
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at android.widget.ImageView.setImageBitmap(ImageView.java:428)
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at com.example.r.MainActivity$1.doInBackground(MainActivity.java:50)
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at com.example.r.MainActivity$1.doInBackground(MainActivity.java:1)
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
 04-11 09:23:25.849: E/AndroidRuntime(8640):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
 04-11 09:23:25.849: E/AndroidRuntime(8640):    ... 5 more
 04-11 09:24:11.209: E/AndroidRuntime(8920): FATAL EXCEPTION: AsyncTask #1
 04-11 09:24:11.209: E/AndroidRuntime(8920): java.lang.RuntimeException: An error occured while executing doInBackground()
 04-11 09:24:11.209: E/AndroidRuntime(8920):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
 04-11 09:24:11.209: E/AndroidRuntime(8920):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
 04-11 09:24:11.209: E/AndroidRuntime(8920):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
 04-11 09:24:11.209: E/AndroidRuntime(8920):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
 04-11 09:24:11.209: E/AndroidRuntime(8920):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
 04-11 09:24:11.209: E/AndroidRuntime(8920):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
 04-11 09:24:11.209: E/AndroidRuntime(8920):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
 04-11 09:24:11.209: E/AndroidRuntime(8920):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
 04-11 09:24:11.209: E/AndroidRuntime(8920):    at java.lang.Thread.run(Thread.java:856)
 04-11 09:24:11.209: E/AndroidRuntime(8920): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
 04-11 09:24:11.209: E/AndroidRuntime(8920):    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:5073)
 04-11 09:24:11.209: E/AndroidRuntime(8920):    at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:1008)
 04-11 09:24:11.209: E/AndroidRuntime(8920):    at android.view.ViewGroup.invalidateChild(ViewGroup.java:4127)
 04-11 09:24:11.209: E/AndroidRuntime(8920):    at android.view.View.invalidate(View.java:10374)
 04-11 09:24:11.209: E/AndroidRuntime(8920):    at android.view.View.invalidate(View.java:10329)
 04-11 09:24:11.209: E/AndroidRuntime(8920):    at android.widget.ImageView.setImageDrawable(ImageView.java:415)
 04-11 09:24:11.209: E/AndroidRuntime(8920):    at android.widget.ImageView.setImageBitmap(ImageView.java:428)
 04-11 09:24:11.209: E/AndroidRuntime(8920):    at com.example.r.MainActivity$1.doInBackground(MainActivity.java:50)
 04-11 09:24:11.209: E/AndroidRuntime(8920):    at com.example.r.MainActivity$1.doInBackground(MainActivity.java:1)
 04-11 09:24:11.209: E/AndroidRuntime(8920):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
 04-11 09:24:11.209: E/AndroidRuntime(8920):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
 04-11 09:24:11.209: E/AndroidRuntime(8920):    ... 5 more

Upvotes: 0

Views: 1043

Answers (2)

Raghunandan
Raghunandan

Reputation: 133560

Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

You cannot update ui from doInBackground

 myImageView.setImageBitmap(circleBitmap);

You need to update ui on the ui thread. Set bitmap to imageview in onPostExecute.

In doInBackground

  return circleBitmap;

In onPostExecute

@Override
public void onPostExecute(Bitmap result)
{
       super.onPostExecute(result);
       myImageView.setImageBitmap(result);
} 

Edit:

 final ImageView myImageView=(ImageView)findViewById(R.id.imageView1);
    AsyncTask<Void, Void, Bitmap> t = new AsyncTask<Void, Void, Bitmap>(){
        protected Bitmap doInBackground(Void... p) {
            Bitmap circleBitmap = null;
            try {
                URL aURL = new URL("https://graph.facebook.com/myfacebookid/picture?type=small");
                URLConnection conn = aURL.openConnection();
                conn.setUseCaches(true);
                conn.connect(); 
                InputStream is = conn.getInputStream(); 
                BufferedInputStream bis = new BufferedInputStream(is); 
                Bitmap bm = BitmapFactory.decodeStream(bis);
                bis.close(); 
                is.close();
                //Bitmap bitmap =;
                circleBitmap = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(), Bitmap.Config.ARGB_8888);

                BitmapShader shader = new BitmapShader (bm,  TileMode.CLAMP, TileMode.CLAMP);
                Paint paint = new Paint();
                        paint.setShader(shader);

                Canvas c = new Canvas(circleBitmap);
                c.drawCircle(bm.getWidth()/2, bm.getHeight()/2, bm.getWidth()/2, paint);
                myImageView.setImageBitmap(circleBitmap);

            } catch (IOException e) { 
                e.printStackTrace(); 
            }
            return circleBitmap;
        }
            @Override
            public void onPostExecute(Bitmap result)
            {
               super.onPostExecute(result);
               myImageView.setImageBitmap(result);
           } 


    };
    t.execute();

Upvotes: 0

Waqar Ahmed
Waqar Ahmed

Reputation: 5068

Since doInBackGround run on seperate thread , you cannot update UI from there. But you can update UI from onPreExecute, onPostExecute and onProgressUpdate beacuse they run on the main thread. Therefore , you can use these method to update UI.

So after downloading image , you can publishProgress to call onProgressUpdate to set image or simply put myImageView.setImageBitmap(circleBitmap); in onPostExecute.

Upvotes: 2

Related Questions