Ermias Asghedom
Ermias Asghedom

Reputation: 95

Drawables won't load using AsyncTask

I have the queryAppIcon() method that queries and stores images in the array appIconDrawable. However, I'm only getting blank where images should pop up. Please let me know if I should post any other relevant code

This is the relevant code inside the ViewActivity:

// global vars
final Drawable[] appIconDrawable = null;
int i;

public Drawable[] queryAppIcon() throws ParseException, IOException {
    ParseQuery<ParseObject> query = ParseQuery.getQuery("AndroidStoreContent");
    query.whereExists("appIcon");
    List<ParseObject> ParseResult = query.find();
    // Drawable array
    appIconDrawable = new Drawable[ParseResult.size()];

    for (i = 0; i < ParseResult.size(); i++) {
        ParseFile pf = (ParseFile) ParseResult.get(i).get("appIcon");
        startDownload(pf);
    }
    return appIconDrawable;
}

public void startDownload(ParseFile pf) {
    new DownloadImageTask(this).execute(pf);
}

public class DownloadImageTask extends AsyncTask<ParseFile, Void, Drawable> {

    private AsyncResponse ar;

    DownloadImageTask(AsyncResponse ar) {
        this.ar = ar;
    }

    @Override
    protected Drawable doInBackground(ParseFile... pf) {
        return fetchDrawable(pf[0]);
    }

    protected void onPostExecute(Drawable result) {
        ar.processFinish(result);
    }

    public Drawable fetchDrawable(ParseFile pf) {
        InputStream is;
        try {
            is = (InputStream) new URL(pf.getUrl()).getContent();
            return Drawable.createFromStream(is,null);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}

@Override
public void processFinish(Drawable d) {
    appIconDrawable[i] = d; // i also tried testing appIconDrawable[1] = d and the app loaded with all blank images and then crashes
}

This is the interface, AsyncResponse:

public interface AsyncResponse {
    void processFinish(Drawable d);
}

Upvotes: 0

Views: 1196

Answers (1)

JRomero
JRomero

Reputation: 4868

It seems like you need a bit of refactor...

You are expecting Drawable[] from queryAppIcon() but you will always get an empty set because you start the download which takes place in a separate thread to then update the return value.

You should be setting the Drawable to the ImageView from within processFinish.

Signs of things done wrong: Async methods such as downloading images should never have a return value.

UPDATE

Here is a very simple download AsyncTask but there are many checks, optimizations, etc. missing, like CACHE! Also, ImageView inside DownloadImageTask should be held by a WeakReference (Google it) otherwise it WILL leak your activity.

public class DownloadImageTask extends AsyncTask<String, Void, Drawable> {

    private static final String TAG = DownloadImageTask.class.getSimpleName();
    private ImageView mImageView;

    DownloadImageTask(ImageView imageView) {
        mImageView = imageView;
    }

    @Override
    protected Drawable doInBackground(String... url) {
        return fetchDrawable(url[0]);
    }

    @Override
    protected void onPostExecute(Drawable result) {
        if (result != null) {
            mImageView.setImageDrawable(result);
        } else {
            Log.w(TAG, "Could download image!");
        }
    }

    public static Drawable fetchDrawable(String url) {
        Log.v(TAG, "Downloading: " + url);
        InputStream is;
        try {
            is = (InputStream) new URL(url).getContent();
            return Drawable.createFromStream(is, null);
        } catch (MalformedURLException e) {
            Log.e(TAG, e.getMessage(), e);
        } catch (IOException e) {
            Log.e(TAG, e.getMessage(), e);
        }

        return null;
    }
}

Adapter:

public class ImageDownloadAdapter extends ArrayAdapter<String>{

    public ImageDownloadAdapter(Context context, String[] objects) {
        super(context, R.layout.item_image_download, R.id.txt_url, objects);
    }

    @SuppressLint("NewApi")
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = super.getView(position, convertView, parent);

        String url = getItem(position);

        ImageView imageView = (ImageView) view.findViewById(R.id.img_download);
        DownloadImageTask downloadImageTask = new DownloadImageTask(imageView);
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            downloadImageTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, url);
        } else {
            downloadImageTask.execute(url);
        }
        return view;
    }
}

Activity:

    ListView listView = (ListView) findViewById(android.R.id.list);
    listView.setAdapter(new ImageDownloadAdapter(this, new String[]{
        "http://www.beautystat.com/site/wp-content/uploads/2011/02/happy-faces-small.jpg",
        "http://www.ducthide.com/new_wallet_pics/happy_face.JPG"
    }));

Upvotes: 1

Related Questions