我正在构建一个应用程序,可以浏览带有大量画廊和照片的互联网站点的图像。以下是该应用程序要执行的步骤:
使用WeakReferences,AsyncTasks使用获取的图像更新(或不更新)所需的视图,从而替换占位符。
打开相册时,我会执行与步骤2相同的步骤,但使用GridView而不是ListView来显示相册内容。
/* GridViewAdapter.getView(...) follows */
public View getView(int position, View convertView, ViewGroup parent)
ImageView thumbnail;
// Recycle or not...
if (convertView == null) {
// Create new View
thumbnail = new ImageView(mContext);
} else {
// Recycle View
thumbnail = (ImageView) convertView;
}
// Set the placeholder Drawable
thumbnail.setImageResource(R.drawable.placeholder);
if (position < amountOfPhotos) {
if (album.getLinks().size() >= 1) {
// imageFetcher creates an AsyncTask for every call of loadThumbnail(...)
imageFetcher.loadThumbnail(thumbnail, album.getURL(position));
}
// Formating the ImageView a little...
...
}
return thumbnail;
问题在于AsyncTasks的性能。当用户滚动列表时,ListView会在我的手机上显示大约7个项目,导致大约12个同步AsyncTasks。这很好,列表仍然很快建立。
现在专辑的GridView一次显示15个项目,滚动列表会创建许多AsyncTasks。由于某些AsyncTasks必须从网上下载,因此它们可以存活几秒钟。这完全减慢了AsyncTasks,它只需要从缓存重新加载位图。
结果是,只要许多AsyncTasks正在运行,GridView就会在向上滚动时不显示图像,即使它只是在几秒钟前显示它们。仅仅因为AsyncTasks太多了。
有关如何解决问题的任何建议?我在想像AsyncTask工厂,我可以在那里排队工作并设置优先级。这样我可以控制下一个执行的作业,我也可以控制一次运行的最大AsyncTasks数量。
如果有人能告诉我一般情况下我的方法是否合适,或者我是否完全在AsyncTasks的错误轨道上,这对我有帮助...
答案 0 :(得分:3)
从Android 3.0
开始,AsyncTasks按顺序执行。因此,一些长期运行的AsyncTasks
将阻止其他人完全有可能。为了同时执行,您可以使用asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
但通常一个好的解决方案是创建ThreadPoolExecutor
并在其上执行Runnables
。这样,您可以控制运行的任务数量并决定使用哪个订单。
答案 1 :(得分:3)
我建议您使用像Picasso这样的库,这样可以非常轻松地下载所有占位符/异步图像!