获取Json数据并转换存入NewsBean类对象之后,由于加载图片不同于文字,加载需要时间,因此用到加载图片的方法,有:1、多线程加载;2、异步加载。
方法一:多线程加载
----新建ImageLoader类,ImageLoader.java文件,类中写public void showImageByThread()方法获取ImageView和url数据,进行转换操作:写一个线程,新建一个getBitmapFromUrl()方法将url数据转换为Bitmap数据
public class ImageLoader {
public void showImageByThread(ImageView imageView, final String url){
new Thread(){
@Override
public void run() {
super.run();
Bitmap bitmap=getBitmapFromUrl(url);
}
}.start();
}
----数据转换部分:
public Bitmap getBitmapFromUrl(String urlString){//通过该方法将url数据解析为Bitmap
Bitmap bitmap;
InputStream is=null;
try {
URL url=new URL(urlString);
HttpURLConnection connection= (HttpURLConnection) url.openConnection();
is=new BufferedInputStream(connection.getInputStream());
bitmap= BitmapFactory.decodeStream(is);
connection.disconnect();//将资源释放
return bitmap;
} catch (java.io.IOException e) {
e.printStackTrace();
}finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
----适配器NewsAdapter的getView方法中new一个ImageLoader进行图片的url向ImageView的转换
new ImageLoader().showImageByThread(viewHolder.ivIcon,mList.get(position).newsIconURL);//把图片对应的url传递给了ImageView
----因为在子线程中不能直接改变UI(Android单线程模型:非主线程不能在线程中直接编程UI),所以无法将Bitmap直接赋给UI,因此只能用Handler进行消息的处理:new一个Handler,重写handleMessage()方法
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
}
};
在showImageByThread()方法中已经用bitmap保存了解析的url数据,需要将bitmap以message的形式发送给Handler:
//发送带有Bitmap的message
Message message=Message.obtain();//obtain();方法对message进行操作
message.obj=bitmap;
handler.sendMessage(message);
声明ImageView mImageView,showImageByThread()方法中用mImageView接收传进来的imageView。
在handleMessage()方法中,通过传进来的message给mImageView设置ImageBitmap:
mImageView.setImageBitmap((Bitmap) msg.obj);
以上,基本实现功能,下面进行优化,主要解决ListView缓存机制在加载图片时的错位问题。
----适配器中运用缓存机制处理多次加载资源消耗问题,在getView方法中,若convertView不为空则将对应图片的url传递给ImageView,在此基础上,为ImageView进行setTag操作将url和ImageView进行绑定:
<span style="font-size:12px;"> viewHolder.ivIcon.setTag(</span><span style="font-size:10px;">mlist.get(position).newsIconURL</span><span style="font-size:12px;">);
new ImageLoader().showImageByThread(viewHolder.ivIcon,mList.get(position).newsIconURL);</span>
在ImageLoader.java中对ImageView的Tag和获取到的URL进行判断,只有相同时才进行图片的加载操作
if (mImageView.getTag().equals(mUrl)) {
mImageView.setImageBitmap((Bitmap) msg.obj);
}