JDS
JDS

Reputation: 16978

Android loading images to listview asynchronously?

I have a listview in which I'm loading all the images (as previews) from the user's SD card. I have a custom SimpleCursorAdapter and when I override the getView() method, I try to start background threads for the image loading.

What I'm trying to do is basically "lazy loading" the image previews into the listview using background threads or something. I'm open for new solutions. The main problem is that scrolling is ungodly slow since loading images is so expensive an operation.

Here's the relevant code I'm trying:

public class listOfImages extends SimpleCursorAdapter {

private Cursor c;
private Context context;


public listOfImages(Context context, int layout, Cursor c,
        String[] from, int[] to) {
    super(context, layout, c, from, to);
    this.c = c;
    this.context = context;

}

public View getView(int pos, View inView, ViewGroup parent) {
    View v = inView;
    if (v == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = inflater.inflate(R.layout.image_item, null);
    }


    this.c.moveToPosition(pos);     
    int columnIndex = this.c.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME);
    String name = this.c.getString(columnIndex);
    columnIndex = this.c.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE);
    String size = this.c.getString(columnIndex);
    columnIndex = this.c.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    String data = this.c.getString(columnIndex); //gives the filename 



    TextView sTitle = (TextView) v.findViewById(R.id.image_title);
    sTitle.setText(name);

    imagePreviewLoader ipl = new imagePreviewLoader(v, data); 
    ipl.mainProcessing(); 


    v.setTag(data); 

    v.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {

            Toast.makeText(context, "Image: " + v.getTag(), Toast.LENGTH_SHORT).show();  

            String filename = (String) v.getTag(); 


            Intent intent = new Intent(context, ViewImage.class);
            intent.putExtra("filename", filename);
            context.startActivity(intent);

        }
    });

    return v; 
}

}

And now the background threading that I'm trying:

public class imagePreviewLoader {

private Handler handler = new Handler(); 
private View v; 
private String data;

public imagePreviewLoader(View v, String data) {
    this.v = v;
    this.data = data; 
}

protected void mainProcessing() {
    Thread thread = new Thread(null, doBackground, "Background"); 
    thread.start(); 
}

private Runnable doBackground = new Runnable() {
    public void run() {
        backgroundThreadProcessing(); 
    }
};

private void backgroundThreadProcessing() {
    handler.post(doUpdateGUI); 
}

private Runnable doUpdateGUI = new Runnable() {
    public void run() {
        updateGUI();
    }
}; 

private void updateGUI() {
    ImageView img = (ImageView) v.findViewById(R.id.image_view); 
    BitmapFactory.Options bfo = new BitmapFactory.Options();
    bfo.inSampleSize = 30;
    bfo.inTargetDensity = 50; 
    Bitmap bm = BitmapFactory.decodeFile(data, bfo);
    img.setImageBitmap(bm);
}

}

The issue is that everything tries to load at once when you scroll, so scrolling is really slow. I thought what would happen is the imageview would just stay blank (or a placeholder) until the thread has loaded the appropriate image. I guess not though.

Thanks for any help.

Upvotes: 1

Views: 5909

Answers (2)

Travis Biehn
Travis Biehn

Reputation: 116

I have an easy to use library under a basically public domain license that you can check out... It will cancel loading for rows that aren't displaying and uses two threads to do image loading.

You can check it out on my GitHub: https://github.com/tbiehn/Android-Adapter-Image-Loader

Upvotes: 1

Kenny
Kenny

Reputation: 5542

Have a look at my answer to this question, it has a sample project which shows how to do it but downloading images from the net. You should be able to modify it quite easily to work for you getting images from the SD card.

Upvotes: 1

Related Questions