Reputation:
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
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
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