0

I am relatively new to android development and i am trying to create a custom ListView with an ImageView and TextView. I am converting a URL into a bitmap image and then trying to display the image in an imageView. However I am getting an error and my application crashes immediately. The was able to display a drawable in my imageView and I made some modifications and tried to display a bitmap and then my application crashed. Any help would be greatly appreciated. Here are my 3 classes :

EDIT I used an asynctask to obtain the bitmap image on a separate thread and now my app does not crash anymore. But it does not display the listview when I start the activity. Here is my updated code.

EDIT I changed my code again and I am only passing an imageView in the execute method of my async task. I am now able to see the text in my listview, but I do not see the image. here is my edited code.

EDIT I used the debugger to find out why the bitmap wasn't getting displayed and i found out that my bitmap variable was null. This was because I had not added internet permissions. After adding the permissions my app started to crash at the given line :

 b = BitmapFactory.decodeStream(image_url.openConnection() .getInputStream());

I had gotten a RuntimeException due to an OutofMemory error. I am not sure how to solve this. i would appreciate any help. thanks !

Here is my Loadimage AsyncTask Class:

 public class LoadImage extends AsyncTask<String, Integer, Bitmap>{

    Context callingContext = null;
    Bitmap b = null;

    ImageView view;

    public LoadImage(ImageView view){

        this.view = view;
    }

    @Override
    protected Bitmap doInBackground(String... arg0) {
        // TODO Auto-generated method stub
        String p_url = "http://java.sogeti.nl/JavaBlog/wp-content/uploads/2009/04/android_icon_256.png";

        Bitmap b = null;
        try {
            URL image_url = new URL(p_url);
            b = BitmapFactory.decodeStream(image_url.openConnection() .getInputStream());

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return b;
    }



    @Override
    protected void onPostExecute(Bitmap result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        view.setImageBitmap(result);

    }   
}
RagHaven
  • 4,156
  • 21
  • 72
  • 113
  • Can you please post the error and backtrace (if appropriate). You can find the backtrace in logcat. – MJD Jul 23 '12 at 16:15
  • 1
    How big are the images you are downloading? On Android, you have a (very) limited memory budget. Depending upon the device, the amount changes but the minimum is 16M (http://stackoverflow.com/questions/1702323/android-available-ram). If the images are really big, you can try looking at: http://stackoverflow.com/questions/477572/android-strange-out-of-memory-issue-while-loading-an-image-to-a-bitmap-object/823966#823966 . – MJD Jul 24 '12 at 13:59

1 Answers1

2

Your code is crashing because you are loading the image file off the server on the UI thread while in strict mode. This is generally considered bad practice because if the image takes a long time to download, your app will appear to have locked up.

Strict mode is forcing the crash (its throwing an exception). If you disable strict mode, it should let your app work fine. However the problem with doing network I/O on your UI thread remains.

The better long term solution is to use something like an AsyncTask. This will load your image on a different thread, thus keeping your app responsive. The documentation for AsyncTask has a simple example for downloading the image, and this helper page has more information.

For an example, I'd probably change your code to something like this (please note I'm writing this without a test run, so there maybe a few bugs):

I'd change your List entry to be:

public class CustomList {

    public String iconUrl;
    public String title;
    public CustomList(){
        super();
    }

    public CustomList(String icon, String title) {
        super();
        this.icon = icon;
        this.title = title;
    }
}

And then only pass in the icon URL's to your list.

Next create an AsyncTask:

public class ImageDownloader extends AsyncTask<String, Integer, Bitmap> {
     public ImageDownloader(ImageView view){
          mView = view;
     }

     protected Bitmap doInBackground(String... url) {
        Bitmap b = null;
        try {
            URL image_url = new URL(url);
            b = BitmapFactory.decodeStream(image_url.openConnection() .getInputStream());
            list_data = new CustomList[]{
                    new CustomList(b,"Android")};
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return b;
     }

     protected void onPostExecute(Bitmap result) {
         mView.setImageBitmap(result);
     }
     ImageView mView;
}

And then for your Adapter, instead of setting the image, do:

new ImageDownloader(holder.thumbnail).execute(cl.icon);

That should be enough to get you started. Please note that there are a couple of issues with this sample:

  1. There is a potential memory leak. Generally speaking you should not hold onto reference to either Views or Activities (or other such objects) in an AsyncTask like I did.
  2. If you rotate the phone and the list changes, you might have old thumbnails show up.
  3. If a view is recycled, an old thumbnail might show up.
MJD
  • 1,183
  • 7
  • 13
  • Thank you for your help ! I tried looking into the helper page, and I couldn't understand how to use the async task along with the custom array adapter to load the bitmap image. I tried using a runnable thread and my application has crashed again. I will edit my code. I would appreciate it if you could tell me where i am going wrong. – RagHaven Jul 23 '12 at 16:55
  • Thanks for your example! But, I was already trying to make my program work with an async task. I have updated my code and I have added the async task class. My current problem is that my listview isnt getting displayed. – RagHaven Jul 23 '12 at 19:11
  • I've changed my code again. i am now doing it the way you have suggested. However, I still am not able to see an image in my listview though I do see the text now. – RagHaven Jul 24 '12 at 03:16