0

I'm using lazy loading images based on this question. I'm implementing a search function that, when the user enters a keyword, the application will do a request and parse the result using SAX and then place the data into a ListView. Sometimes the images can be loaded into ImageViews of the ListView rows but sometimes it will load only one or two images and the application crashes.

Below is my LogCat output:

05-16 16:37:37.414: ERROR/AndroidRuntime(620): FATAL EXCEPTION: Thread-11
05-16 16:37:37.414: ERROR/AndroidRuntime(620): java.lang.NullPointerException
05-16 16:37:37.414: ERROR/AndroidRuntime(620):     at com.TPLibrary.Search.ImageLoader.getBitmap(ImageLoader.java:71)
05-16 16:37:37.414: ERROR/AndroidRuntime(620):     at com.TPLibrary.Search.ImageLoader.access$0(ImageLoader.java:68)
05-16 16:37:37.414: ERROR/AndroidRuntime(620):     at com.TPLibrary.Search.ImageLoader$PhotosLoader.run(ImageLoader.java:173)

Below is where the errors are occuring at:

private Bitmap getBitmap(String url) { // line 68
    //I identify images by hashcode. Not a perfect solution, but ok for the demo
    String filename = String.valueOf(url.hashCode()); // line 71
    File f = new File(cacheDir, filename);

    //from SD cache
    Bitmap b = decodeFile(f);
    if (b != null)
        return b;

    //from web
    try {
        Bitmap bitmap = null;
        InputStream is = new URL(url).openStream();
        OutputStream os = new FileOutputStream(f);
        Utils.CopyStream(is, os);
        os.close();
        bitmap = decodeFile(f);
        return bitmap;
    } catch (Exception ex){
        ex.printStackTrace();
        return null;
    }
}

class PhotosLoader extends Thread {
    public void run() {
        try {
            while(true)
            {
                //thread waits until there are any images to load in the queue
                if (photosQueue.photosToLoad.size() == 0)
                    synchronized(photosQueue.photosToLoad) {
                        photosQueue.photosToLoad.wait();
                    }
                if (photosQueue.photosToLoad.size() != 0) {
                    PhotoToLoad photoToLoad;
                    synchronized(photosQueue.photosToLoad) {
                        photoToLoad=photosQueue.photosToLoad.pop();
                    }
                    Bitmap bmp = getBitmap(photoToLoad.url); // line 173
                    cache.put(photoToLoad.url, bmp);
                    Object tag = photoToLoad.imageView.getTag();
                    if (tag != null && ((String)tag).equals(photoToLoad.url)){
                        BitmapDisplayer bd =
                            new BitmapDisplayer(bmp, photoToLoad.imageView);
                        Activity a = (Activity)photoToLoad.imageView.getContext();
                        a.runOnUiThread(bd);
                    }
                }
                if (Thread.interrupted())
                    break;
            }
        } catch (InterruptedException e) {
            //allow thread to exit
        }
    }
}

EDIT
I have tracked down the NullPointerException that comes from the PhotoToLoad class below:

private class PhotoToLoad {
    public String url;
    public ImageView imageView;
    public PhotoToLoad(String u, ImageView i) {
        url = u; 
        imageView = i;
    }
}

How can I solve the problem?

Community
  • 1
  • 1
Joel Seah
  • 674
  • 3
  • 13
  • 34

2 Answers2

3

It seems that you pass null to this method. Make sure that you handle null appropriately, or make sure you don't pass null there (first is better ;)).


Your error log indicates, the NPE occurs in
String filename=String.valueOf(url.hashCode());

So, url is null at this point. So Either you integrate a check like

if (url == null) {
    Log.w("null has been passed to getBitmap()");
    return null;
}

or you have a look on every call where you pass null to this method making it crash.

Stephan
  • 7,360
  • 37
  • 46
  • I added some more explanations to my post. I hope it is clearer now. – Stephan May 16 '11 at 09:58
  • Thanks. I solved the issue. I just replace the null image with a drawable item and it wont crash anymore. Thanks to you and Octcavion! – Joel Seah May 17 '11 at 09:01
0

Remove return null from your catch() block because this might be throwing an Exception and the Bitmap is getting NULL object.

Sujit
  • 10,512
  • 9
  • 40
  • 45
  • Depends on what you what to happen. If it's relly critical, let the program crash with a message to tell to the dev. Or you handle it and give the user maybe some feedback what he or she did wrong. There are lots of different possibilities... – Beasly May 16 '11 at 10:02
  • What I want is that the application will download the images and place them into the ImageViews. Instead of crashing. – Joel Seah May 17 '11 at 07:18