为什么使用异步任务在Imageview中没有设置图像?

时间:2014-04-11 04:04:43

标签: android bitmap android-asynctask

我正在尝试使用网址和异步任务检索Facebook个人资料照片。我使用以下代码,我已发布错误日志。请告诉我出了什么问题。

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();

错误日志:

 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

2 个答案:

答案 0 :(得分:2)

由于doInBackGroundseperate thread上运行,您无法从那里更新UI。但是您可以从onPreExecute, onPostExecute and onProgressUpdate更新UI,因为它们在主线程上运行。因此,您可以使用这些方法来更新UI。

因此,下载图片后,您可以发布进度以调用onProgressUpdate来设置图片,或者只是将myImageView.setImageBitmap(circleBitmap);放入onPostExecute.

答案 1 :(得分:0)

  

引起:android.view.ViewRootImpl $ CalledFromWrongThreadException:   只有创建视图层次结构的原始线程才能触及它   视图。

您无法从doInBackground

更新ui
 myImageView.setImageBitmap(circleBitmap);

您需要在ui线程上更新ui。在onPostExecute中将位图设置为imageview。

doInBackground

  return circleBitmap;

在onPostExecute

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

编辑:

 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();