0

I am continuing my efforts in making an app for my school newspaper. My newest challenge is to get every club and organization logo to appear in a ImageView that is in an Activity with other details about the club.

For obvious reasons I don't want to store all of these images within the app, I would rather fetch them from a URL. I think a way to do this would be the following snippet:

Intent intent = getIntent();
 Bitmap bm = null;
try {
    bm = BitmapFactory.decodeStream((InputStream)new URL(intent.getStringExtra("keyLogo")).getContent());
} catch (MalformedURLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
 detailsLogo.setImageBitmap(bm);

I am getting a URL from an XML file that I created which has all of the clubs on campus and their information. This way I only have to change the XML when I want to change something within the app.

The problem here is that it throws a NetworkOnMainThread exception. Could this be put into an AsyncTask within my activity and run that way? Any advice would be appreciated.

EDIT: The linked question does not answer my needs. One of the answers to it is close, but my questions specifically needs an Async task which that questions accepted answer does not include.

Here is the finished activity using the accepted answer and other pieces:

public class OrgDetails extends Activity {

/*******************************************************************
 * Async Task
 ******************************************************************/
private class GetImageFromServer extends AsyncTask<String, Void, Bitmap> {

    String url;
    Context context;
    private Bitmap image;
    ImageView detailsLogo = (ImageView)findViewById(R.id.detailsLogo);

    public GetImageFromServer(String url, Context context){
        this.url = url;
        this.context = context;
    }

    @Override
    protected Bitmap doInBackground(String... params){
        try{
            URL urli = new URL(this.url);
            URLConnection ucon = urli.openConnection();
            image = BitmapFactory.decodeStream(ucon.getInputStream());
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return image;  //<<< return Bitmap
    }
    @Override
    protected void onPostExecute(Bitmap result){ 
        detailsLogo.setImageBitmap(result);
    }

}
/*******************************************************************
 * End Async Task
 ******************************************************************/

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.orgdetails);

     TextView detailsSname = (TextView)findViewById(R.id.detailsSname);
     TextView detailsLname = (TextView)findViewById(R.id.detailsLname);
     TextView detailsDescription = (TextView)findViewById(R.id.detailsDescription);

     Intent intent = getIntent();

     detailsLname.setText(intent.getStringExtra("keyLname"));
     detailsSname.setText(intent.getStringExtra("keySname"));
     detailsDescription.setText(intent.getStringExtra("keyDescription"));

     String str_url = intent.getStringExtra("keyLogo");
     GetImageFromServer asyObj = new GetImageFromServer(str_url,OrgDetails.this);
     asyObj.execute("");
}

}
Yaminick
  • 35
  • 8
  • http://stackoverflow.com/questions/2471935/how-to-load-an-imageview-by-url-in-android/2472175#2472175 – yarian Feb 25 '13 at 23:07
  • If you add in the code sample where you expect to use an Async task you have more chance to get a correct aswwer – rene Feb 26 '13 at 21:07

3 Answers3

3

Change your code using AsyncTask for getting image from sever instead of doing Network Operation on Main UI thread. Create an inner class of Activity by extending AsyncTask as:

private class GetImageFromServer extends AsyncTask<String, Void, Bitmap> {

     String url;
     Context context;
     public GetImageFromServer(URL url,Context context){
       this.url=url;
       this.context=context;
        }
      @Override
      protected Bitmap doInBackground(String... params) {
        bm = BitmapFactory.decodeStream((InputStream)new URL(url).getContent());
        return bm;  //<<< return Bitmap
      }      

      @Override
      protected void onPostExecute(Bitmap result) { 
            detailsLogo.setImageBitmap(result);  
      }

}

and execute AsyncTask as from Activity:

String str_url=intent.getStringExtra("keyLogo");
GetImageFromServer asyObj=new GetImageFromServer(str_url,Your_Activity.this);
asyObj.execute("");
ρяσѕρєя K
  • 132,198
  • 53
  • 198
  • 213
3

You get a NetworkOnMainThread exception as you are attempting to perform network operations in the UI thread.

You should put this into an AsyncTask as you suggested, and your download code should retrieve the InputStream rather than cast the content like so:

URL url = new URL(path);
URLConnection ucon = url.openConnection();
Bitmap image = BitmapFactory.decodeStream(ucon.getInputStream());

If you also want more flexible control over your images, consider using Image adapters for your Bitmap objects. These are containers that extend the BaseAdapter and can provide you extra controls to manipulate your images e.g. scaling.

Hakan Ozbay
  • 4,639
  • 2
  • 22
  • 28
  • I accepted the answer above only because it was more detailed, but I implemented your code as well, thank you. – Yaminick Feb 26 '13 at 21:18
0

Yes you definitely want to do your grabbing of images over the network on a separate thread. You could set up your doInBackground to get the image and then in the onpostexecute set the bitmap to the imageview.

James andresakis
  • 5,335
  • 9
  • 53
  • 88