接上,进一步优化,LruCache缓存

时间:2021-08-17 09:45:26

为了节省流量,提高应用的流畅性,采用Lru算法

Lru(Least Recently Used)近期最少使用算法

Android提供了LruCache类来实现这个缓存算法,典型的以内存换效率的办法

最终优化完的完整的ImageLoader类的代码为:

public class ImageLoader{

private ImageView mImageView;
private Handler mHandler = new Handler();
private String mUrl;
private LruCache<String, Bitmap> mCaches;//创建Cache

public ImageLoader(){
int maxMemory = (int)Runtime.getRuntime().maxMemory();//获取最大的可用内存
int cacheSize = maxMemory/4;
mCaches = new LruCache<>(cacheSize){
protected int sizeOf(String key, Bitmap value){
return value.getByteCount();//在每次存入缓存的时候调用
}
};
}

public void addBitmapToCache(String url, Bitmap bitmap){
//增加到缓存
if(getBitmapFromCache(url) == null){
mCaches.put(url, bitmap);
}
}

public Bitmap getBitmapFromCache(String url){
//从缓存中获取数据
return mCaches.get(url);
}


private Handler handler = new Handler(){
public void handleMessage(Message msg){
super.handleMessage(msg);
if(mImageView.getTag().equals(mUrl))
mImageView.setImageBitmap((Bitmap)msg.obj);
}
}

public void showImageByThread(ImageView imageView, String url){
mImageView = imageView;
mUrl = url;
new Thread(){
public void run(){
super.run();
Bitmap bitmao = getBitmapFromURL(url);
Message message = Message.obtain();
message.obj = bitmap;
mHandler.sendMessage(message);
}
}.start();
}

public Bitmap getBitmapFromURL(String urlStirng){
Bitmap bitmap;
InputStream is;
try{
URL url = new URL(urlStirng);
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{
is.close();
}
return null;
}
}

public void showImageByAsyncTask(ImageView imageView, String url){
//从缓存中取出对应的图片,若缓存中没有,则去网络下载
Bitmap bitmap = getBitmapFromCache(url);
if(bitmap == null){
new MyAsyncTask(imageView, url).execute(url);
}else{
//缓存中有图片,则直接使用
imageView.setImageBitmap(bitmap);
}

}

private class MyAsyncTask extends AsyncTask<String, Void, Bitmap>{

private ImageView imageView;
private String mUrl;


public MyAsyncTask(ImageView imageView, String url){
mImageView = imageView;
mUrl = url;
}
protected Bitmap doInBackground(String... params){
String url = params[0];
//从网络获取图片
Bitmap bitmap = getBitmapFromURL(url);
if(bitmap != null){
//将不在缓存的图片加入缓存
addBitmapToCache(url,bitmap)
}
return bitmap;
}

protected void onPostExecute(Bitmap bitmap){
super.onPostExecute(bitmap);
if(mImageView.getTag().equals(mUrl))
mImageView.setImageBitmap(bitmap);
}
}
另外,还需要在MyAdapter类中再初始化一个对象:

public class MyAdapter extends BaseAdapter{
private List<MyBean> mList;
private LayoutInflater mInflater;
private ImageLoader mImageLoader;

public MyAdapter(Context context, List<MyBean> data){
mList = data;
mInflater = LayoutInflater.from(context);
mImageLoader = new ImageLoader();
}
这样就保证了只有一个LruCache