Reputation: 95
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
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