最有意思的事情,是我和你眼中的世界是这般的不一样。
希望能够和你多交流,认识到我认识不到的世界。
/**
* 》》》》》》!专门用于处理图片的加载!《《《《《《
*
* 实现异步加载,主要使用两种方式,一种是多线程的方式,一种是AsyncTask 的方式,
* 在网上好像看到还有第三种方式,是自己写代码处理?
* Created by pc on 2016/10/4.
*/
public class ImageLoader {
private ImageView mImageView;
private String mUrl;
private Handler mHandler = new Handler() {
@Override
// 从副线程中加载图片,然后将图片信息返回 handleMessage 中进行处理,最后在主线程中调用 handleMessage 即可更新 UI
public void handleMessage(Message msg) {
super.handleMessage(msg);
// 由于convertView缓存池读取出现问题,进行判断,避免缓存图片对正确图片产生的影响。
if (mImageView.getTag().equals(mUrl)) {
mImageView.setImageBitmap((Bitmap) msg.obj);
Log.d("Success", mUrl);
} else {
Log.d("Fail", mUrl);
}
/**
* 当程序运行到这里的时候,通过给程序添加一个加载时间,我们会发现一些问题,出现图片跳动问题,造成item错乱。
* 由于ListVIew具有重用convertVIew的功能,在图片加载之前,会调用缓冲池中已经存在的图片,
* 从而使得先加载缓存池再加载图片的后果。
*
*/
}
};
/**
* 1、从NewsAdapter中引入匿名内部类的方式,将ImageVIew的图片加载方式引入在ImageLoader方法之中
* 2、通过多线程的方式,需要使用 Thread 中的方法,我们新建一个Thread方法
*
* @param imageView
* @param url
*/
public void showImageByThread(ImageView imageView, final String url) {
mImageView = imageView;
mUrl = url;
// 通过下面的Thread的方法,我们就可以打开一个新的线程去处理ImageLoad事件
new Thread() {
@Override
public void run() {
super.run();
// 在run方法中增加对图片的处理方法,对图像的处理我们需要传入一个 Bitmap 对象
Bitmap bitmap = getBitmapFromUrl(url);
/**
* 那么,千辛万苦获取到了Bitmap,是不是可以将 Bitmap对象 赋予ImageView呢? 当然不可以,
* 主要原因是当前的方法时处于非主线程之中,Android当中,非主线程是不可以更新UI的。
* 于是,我们又要用到Handler方法来实现更新UI.
* 1、创建一个Handler 对象,
* 2、message.obj = bitmap; 另message 的obj 对象等于 bitmap
* 3、handler.sendMessage(message); 将带有Bitmap对象的message传递给Handler
* 4、handler 收到了 message 之后,自然就需要对 message 进行处理,我们先新建一个ImageView
* 5、然后通过Handler的handleMessage方法,ImageView.setImageBitmap((Bitmap) msg.obj);
* 将message.obj中的Bitmap对象赋值到ImageView
* 6、Message message = Message.obtain();
* 通过这种方式获取的Message,可以是用现有的,以及回收到的Message,提高Message的使用效率。
*/
Message message = Message.obtain();
message.obj = bitmap;
mHandler.sendMessage(message);
}
}.start();
}
// 由于从Adapter中传入的是 url 对象,我们要新建一个方法将url 转化成Bitmap对象,新建一个方法,传入 url 实例,返回Bitmap对象
public Bitmap getBitmapFromUrl(String urlString) {
Bitmap bitmap;
InputStream is = null;
try {
/**
* ------------> 通过getBitmap方法将urlString转化为Bitmap对象<--------------------
* 通过 URL url = new URL(urlString); 的方式,将urlString转化为url。
* 然后 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); Http的链接方式打开并获取到url中的图片内容。
* 读取到了一个 connection 对象,我们就可以新建一个InputStream,通过connection来获取到InputStream对象
* 再者,通过Buffered的方法,读取到is的内容 is = new BufferedInputStream(connection.getInputStream());
* 最后,有个InputStream对象,我们就可以通过 bitmap = BitmapFactory.decodeStream(is); 将InputStream对象转化成Bitmap对象
* 结尾,将网络读取的资源进行释放 connection.disconnect(); 以及finally{is.close();}
* 在Java中,凡是和网络相关的,大多要使用try-catch捕捉异常
* ------------> 通过getBitmap方法将urlString转化为Bitmap对象<--------------------
*/
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
is = new BufferedInputStream(connection.getInputStream());
bitmap = BitmapFactory.decodeStream(is);
connection.disconnect();
// 听我号令,睡眠吧!
// Thread.sleep(500);
return bitmap;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
// } catch (InterruptedException e) {
// e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
public void showImageFromAsyncTask(ImageView imageView, final String url) {
new MyAsncyTask(imageView,url).execute(url);
}
private class MyAsncyTask extends AsyncTask<String, Void, Bitmap> {
private String mUrl ;
private ImageView mImageView ;
public MyAsncyTask(ImageView imageView ,String url) {
mImageView = imageView;
mUrl = url;
}
@Override
protected Bitmap doInBackground(String... params) {
return getBitmapFromUrl(params[0]);
}
@Override
// 在这个方法中我们获取了Bitmap对象,然后我们需要外部传递进来一个ImageVIew对象,在构造方法中添加.
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
if (mImageView.getTag().equals(mUrl)) {
mImageView.setImageBitmap(bitmap);
Log.d("Success", mUrl);
} else {
Log.d("Fail", mUrl);
}
}
}
}