Monday, October 31, 2011

java thread VS. android AsyncTask


this is a comparasion between java thread and android AsyncTask in case of speed.
for my file manager application i want do thumbnail creation in seperate thread in background, so first i used AsyncTask class. here is it's code :

private class backgroundThumbnailLoader extends AsyncTask
{
int count = 0;
Drawable ic;
protected void onPreExecute()
{
setProgressBarIndeterminateVisibility(true);
}
protected Void doInBackground(Void... unused)
{
for(String item : items)
{
String pathTemp = currentPath + item;
Drawable ic = createThumb(pathTemp);
publishProgress(ic);
}
return null;
}
protected void onProgressUpdate(Drawable... icon)
{
iHolder.get(count).setIcon(icon[0]);
count++;
RA.notifyDataSetChanged();
}
protected void onPostExecute(void unused)
{
setProgressBArIndeterminateVisibility(false);
}
}

count : is a counetr for holding icon's position.
items : is a String array of items in currentPath of sdcard.
createThumb() : is a simple method that get path of item in sdcard and 
return a thumbnail for it.(its code does not matter, because it is 
constant in both AsyncTask and basic thread)
iHolder : is an ArrayList of Drawable (icon holder)
RA : is a custome ArrayAdapter for items (every time an icon created
it being updated via notifyDataSetChanged() )

then i execute my file manager, wow, its icon loading is terrible even worse than when it created in UI Tread.
the sdcard contain 25 items including folder, jpg, gif, apk, txt, jar, pdf, 3gp.
i get the time when progressBar appear until it disappear. it take 21.40 sec for loading all thumbnail.(i know it is terrible for file manager)

first i think there most be a problem in createThumb() method, so i replace it with this simple code : getResources().getDrawable(R.drawable.xxx);
this code is just a simple resource access that cost nothing in time. but the time of loading this simple thumbnail is still terrible. (something about 18 sec)
so i decide write a traditional java thread for it. here is the code :

public void thumbnail()
{
    setProgressBarIndeterminateVisibility(true);
    Thread iconThread = new Thread(null, makeThumb, "backgroundThumb");
    iconThread.start();
}
private Runnable makeThumb = new Runnable()
{    
    public void run()
    {
    try
    {
    for(int i = 0 ; i < items.length ; i++)
        {
        if(cancelThumbnail)
        return;
        String tempPath = currentPath + items[i];
        Drawable ic = createThumb(tempPath);
        iHolder.get(i).setIcon(ic);
        Message msg = thumbnailHandler.obtainMessage(MESSAGE_ICON_CHANGED);
            thumbnailHandler.sendMessage(msg);
        }
        Message msg = thumbnailHandler.obtainMessage(MESSAGE_ICON_LOAD_END);
        thumbnailHandler.sendMessage(msg);
    }
    catch(IndexOutOfBoundsException e)
    {
    Message msg = thumbnailHandler.obtainMessage(MESSAGE_OUT_OF_BOUNDS);
    thumbnailHandler.sendMessage(msg);
    }
   
    }
};
private Handler thumbnailHandler = new Handler()
{
    public void handleMessage(Message msg)
    {
    switch(msg.what)
    {
    case MESSAGE_ICON_CHANGED:
    RA.notifyDataSetChanged();
    break;
    case MESSAGE_ICON_LOAD_END:
    setProgressBarIndeterminateVisibility(false);
    break;
    case MESSAGE_OUT_OF_BOUNDS:
    display();
    break;
    }    
    }
};

then i execute file manager, again wow, thumbnail loading is much much faster, about 5.80 sec.
you can see the only diffrence between this two code is just using AsyncTask VS. java Thread.
again i think why this happens, perhaps some part of my code has problem, so i google it and found this blog :

http://mihaifonoage.blogspot.com/2009/09/displaying-images-from-sd-card-in.html
http://mihaifonoage.blogspot.com/2009/11/displaying-images-from-sd-card-in.html

that guy write a code that do something, first in UI Thread, and second in AsyncTask,, what the code does is not matter, the matter is that AsyncTask do the job much slower.(you can test it yourself)

AS RESULT : if you need SIMPLE coding use AsyncTask and if you need SPEED use traditional java Thread.









No comments: