Let me just start by saying I have a rather unusual source of images. I'm getting the bitmaps that need to be loaded from ID3 tags on an mp3 file.

Whenever I load the cover art and save it to the SD storage I get lagg. The odd thing is that all the loading and saving is happening on a background thread so it should not influence the UI thread. + I'm only running one operation at a time and it still laggs.

Once I have saved all the images to disk and I construct an array with all path names to the saved files it scrolls like butter and all images load without any delay. So the issue clearly is the caching to SD which is not happening on the UI thread. (I might be wrong about it though, so that is where you guys come in) The image loading from file is done using Universal Image Loader btw, but that is not causing any problems :)

Here is a snippet of my code that stores the cover art:

```
public ExecutorService executor = Executors.newFixedThreadPool(1);

//this is where I schedule tasks for all mp3 files to be executed using the threadpool, 
//it is interrupted as soon as the user interacts with the listview (which should not be
//nessecary as it is not running any code on the UI thread)

public void preloadImages(){
    for(int i = 0; i < items.length; i++){
        if(scrolling){
            return;
        }
        if(items[i].type.equalsIgnoreCase("music") && imagePathArray[i] == null){
            ImageRunnable imgr = new ImageRunnable(items[i].pathname, null, i);
            executor.execute(imgr);
        }
        if(scrolling){
            return;
        }
    }
}

```

custom runnable

```
//the custom runnable used to call the getCover method on separate thread
private class ImageRunnable implements Runnable {
    private String url;
    private final WeakReference<ImageView> imageViewReference;
    private boolean running = true;
    private int position;

    public ImageRunnable(String path, ImageView img, int pos) {
        url = path;
        imageViewReference = new WeakReference<ImageView>(img);
        position = pos;
    }

    public void terminate() {
        running = false;
    }

    @Override
    public void run() {
        android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
        final String coverPath = getCover(url, position);
    }
}

```

The getcover method

```
private String getCover(String filepath, boolean refresh, int pos){
    Log.d(LOG_TAG, "BEGIN function");
    File file = new File(filepath);
    Log.d(LOG_TAG, "File read");
    MusicMetadataSet meta = null;

    try {
        meta = new MyID3().read(file);
        Log.d(LOG_TAG, "id3 read");
    } catch (IOException e) {
        Log.d(LOG_TAG, "error reading id3 tag of file");
        return null;
    }
    if(meta != null) {
        try {
            MusicMetadata metasimple = (MusicMetadata) meta.getSimplified();
            Log.d(LOG_TAG, "simplified");
            int length = filepath.length();
            String albumname = filepath.substring(length-15, length-5).replaceAll("[^a-zA-Z0-9.-]", "_");
            String path = Environment.getExternalStorageDirectory().toString();
            OutputStream fOut = null;
            Log.d(LOG_TAG, "album string");
            File fileo = new File(path, "id3tag/"+albumname+"_icon.jpg");
            Log.d(LOG_TAG, "file created");
            File dir = new File(path, "id3tag/");
            if(!dir.isDirectory()){
                dir.mkdirs();
            }
            if(!fileo.exists() || refresh){
                try {
                    fileo.createNewFile();
                    fOut = new FileOutputStream(fileo);

                    Vector<ImageData> fileList = metasimple.getPictureList();
                    Log.d(LOG_TAG, "got pic list");
                    ImageData data = fileList.lastElement();
                    if(fileList.size() == 0){
                        imagePathArray[pos] = "error";
                        return imagePathArray[pos];
                    }
                    byte[] rawimage = data.imageData;
                    Log.d(LOG_TAG, "got raw");
                    Bitmap bitmap = BitmapFactory.decodeByteArray(rawimage, 0, rawimage.length);
                    Log.d(LOG_TAG, "decoded bmp");
                    bitmap = bitmap.createScaledBitmap(bitmap, 64, 64, false);
                    Log.d(LOG_TAG, "scaled bmp");
                    bitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
                    Log.d(LOG_TAG, "compr bmp");
                    fOut.flush();
                    fOut.close();
                    bitmap.recycle();
                    Log.d(LOG_TAG, "recycled");

                    meta = null;
                    rawimage = null;
                    fileList = null;
                    options = null;
                    metasimple = null;
                    bitmap = null;
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            imagePathArray[pos] = Uri.decode(fileo.toURI().toString().replace("file:/", "file:///"));
            return imagePathArray[pos];
        }catch (NoSuchElementException e){
            return null;
        }
    }
    return null;
}

```