ListView异步加载网络图片之一
前面用了三篇文章来写有关ListView性能优化,这一个文章,将讲解从网络异步加载图片,然后显示到列表中。由于需要异步加载,所以这里会用到AsyncTask这个类。
AsyncTask:他是Android提供的一个异步任务组件,他会开启一个后台线程,最后将执行的结果返回到UI线程,并且不用我们去操纵thread和handler,非常的方便。
注意:在AndroidManifest.xml中添加网络访问的权限,新手很容易忘掉的。。。如果网络的权限都没有,神马都是浮云了
<uses-permission android:name="android.permission.INTERNET" />
- 重写adapter的getView方法
@Override public View getView(int position, View convertView, ViewGroup parent) { Log.d(TAG, "position=" + position + ",convertView=" + convertView); ViewHolder viewHolder = null; if (convertView == null) { convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item, null); viewHolder = new ViewHolder(); viewHolder.mTextView = (TextView) convertView.findViewById(R.id.tv_tips); viewHolder.mImageView = (ImageView) convertView.findViewById(R.id.iv_image); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } Bitmap bitmap = getImage(position);//从缓存中取图片 if (bitmap != null) { viewHolder.mImageView.setImageBitmap(bitmap); } else {// 缓存没有就设置为默认图片,并且从网络异步下载 viewHolder.mImageView.setImageResource(R.drawable.ic_launcher); ImageLoadTask imageLoadTask = new ImageLoadTask(); String url = ""; if (position % 2 == 0) { url = URL_ITEYE_LOGO; } else { url = URL_MY_LOGO; } imageLoadTask.execute(viewHolder, url, position);//执行异步任务 } viewHolder.mTextView.setText("-----" + position); return convertView; }
- 下面开始写我们的异步任务ImageLoadTask他需要继承AsyncTask,并且重写他的doInBackground(运行在后台线程)和onPostExecute(返回UI线程执行)方法
class ImageLoadTask extends AsyncTask<Object, Void, Bitmap> { ViewHolder mHolder; int position; @Override protected Bitmap doInBackground(Object... params) { mHolder = (ViewHolder) params[0]; String url = (String) params[1]; position = (Integer) params[2]; Bitmap drawable = ImageLoader.loadImage(url);//获取网络图片 return drawable; } @Override protected void onPostExecute(Bitmap result) { if (result == null) { return; } mHolder.mImageView.setImageBitmap(result); cacheImage(position, result);//放入缓存 } }
- 下载网络图片
public class ImageLoader { public static Bitmap loadImage(String url) { Bitmap bitmap = null; HttpClient client = new DefaultHttpClient(); HttpResponse response = null; InputStream inputStream = null; try { response = client.execute(new HttpGet(url)); HttpEntity entity = response.getEntity(); inputStream = entity.getContent(); bitmap = BitmapFactory.decodeStream(inputStream); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return bitmap; } }
总结:为了让ListView更加的流程,所以耗时的网络请求必须要开启一个异步任务,防止UI线程被阻塞。所以这篇文章的重点就是AsyncTask。这个demo有两个很严重的bug,有兴趣的同学下载源码运行一下就会发现这两个bug,我会在接下来的文章中解决这两个恶心的bug。好了非常感谢您把这篇文章看完了。