mg4377娱乐娱城官网_mg4377娱乐手机版_www.mg4377.com

【mg4377娱乐手机版】从网络获取图片并缓存,A

时间:2019-06-06 17:18来源:mg4377娱乐手机版
获得一张图纸,从多少个地点开展获取,首先是内存缓存,然后是文件缓存,最终才从互连网中获得。```java 倘若每一趟加载同一张图片都要从互连网得到,那代价实在太大了。所以壹

获得一张图纸,从多少个地点开展获取,首先是内存缓存,然后是文件缓存,最终才从互连网中获得。```java

倘若每一趟加载同一张图片都要从互连网得到,那代价实在太大了。所以壹律张图纸只要从网络得到叁遍就够了,然后在地方缓存起来,之后加载同一张图纸时就 从缓存中加载就可以了。从内部存款和储蓄器缓存读取图片是最快的,可是因为内部存款和储蓄器体积有限,所以最佳再加上文件缓存。文件缓存空间也不是Infiniti大的,体量越大读取功效越 低,因而能够安装叁个限量大小比方10M,可能限制保存时间比方一天。
由此,加载图片的流水线应该是:
一、先从内部存款和储蓄器缓存中收获,取到则赶回,取不到则开始展览下一步;
贰、从文件缓存中得到,取到则赶回并更新到内部存款和储蓄器缓存,取不到则举行下一步;

原演示地址

一、内部存款和储蓄器缓存(一流)

public class MemoryCacheUtils {

寄存图片的集结

private HashMap<String,SoftReference<Bitmap>> mHashMap =new HashMap<>();

设置超级缓存(原理)

public void setMemoryCache(String url, Bitmap bitmap){

SoftReference<Bitmap> softReference=new SoftReference<Bitmap>(bitmap);

mHashMap.put(url,softReference);

mLruCache.put(url,bitmap); 

}

得到一流缓存(原理)

public Bitmap getMemoryCache(String url){

SoftReference<Bitmap> softReference =mHashMap.get(url);

if(softReference != null){

Bitmap bitmap =softReference.get();

return bitmap;

}

return null;

return mLruCache.get(url);

}

}

优化:使用LruCache算法(least recentlly used cache),拜别软引用和弱引用,内部基本是透过算法达成缓存的大大小小决定,封装HashMap,使用更为便利轻易。使用LruCache代替上述的HashMap。

private LruCache<String,Bitmap> mLruCache;

构造方法开头化LruCache

public MemoryCacheUtils(){

//获取虚拟机分配的最大内部存款和储蓄器,暗中同意16M

 long maxMemory = Runtime.getRuntime().maxMemory();

//参数是内存缓存上限

mLruCache =new LruCache((int) (maxMemory/8)){

@Override

 protected int sizeOf(String key, Bitmap value) {

//获取单个对象占用字节数大小

//int byteCount = value.getByteCount();

//包容低版本,壹行字节数*总行数

  int byteCount =value.getRowBytes()*value.getHeight();

//再次来到单个对象占用内部存款和储蓄器大小

 return byteCount;

}

};


//内部存款和储蓄器缓存

3、从互连网下载图片,并创新到内部存款和储蓄器缓存和文书缓存。

 

2、本地缓存(二级)

public class LocalCacheUtils {

急需寄放本地缓存的目录路线

String path = Environment.getExternalStorageDirectory().getAbsolutePath() "/自定义/";

安装本地缓存

public void setLocalCache(String url, Bitmap bitmap) {

File dir =new File(path);

if (!dir.exists() || !dir.isDirectory()) {  // 不存在 或然 不是目录

//创制此抽象路线名内定的目录 //dir.mkdir();

//创立此抽象路径名钦赐的目录,包含持有要求但不设有的父目录。

 dir.mkdirs();

}

//url须要通过管理

  File file =new File(dir, url);

//将图片压缩到地头

 try {

【mg4377娱乐手机版】从网络获取图片并缓存,Android之图片三级缓存。//参数1是图片格式,参数2是削减比(0-100),100代表不减弱,参数叁是文本输出流   bitmap.compress(Bitmap.CompressFormat.JPEG,拾0,new FileOutputStream(file));

}catch (FileNotFoundException e) {

e.printStackTrace();

}

}

获得本地缓存

public Bitmap getLocalCache(String url) {

//url要求通过管理

  try {

File cacheFile =new File(path, url);

if (cacheFile.exists()) {  //缓存存在

 Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(cacheFile));

return bitmap;

}

}catch (Exception e) {

e.printStackTrace();

}

return null;

}

}


public class ImageMemoryCache {

接下去看内部存款和储蓄器缓存类:ImageMemoryCache
public class ImageMemoryCache {
/**
* 从内部存款和储蓄器读取数据速度是最快的,为了越来越大限度使用内部存款和储蓄器,这里运用了两层缓存。
* 硬引用缓存不会随意被回收,用来保存常用数据,临时用的转入软引用缓存。
*/
private static final int SOFT_CACHE_SIZE = 1伍; //软引用缓存容积
private static LruCache<String, Bitmap> mLruCache; //硬引用缓存
private static LinkedHashMap<String, SoftReference<Bitmap>> mSoftCache; //软引用缓存

本文内容

  • 环境
  • 示范 LazyList 从网络得到图片并缓存
  • 仿照效法资料

本文是 Github 上的八个示范,通过网络获取明星专辑的缩略图,并体未来ListView 控件中。该演示具有将缩略图缓存到手提式有线电电话机外部存款和储蓄器的意义,所以叫“Lazy”,那样就不用每便都经过网络重新获得。在上学那几个演示前,希望您对 Android 的 Adpater 相关有分明的领会。

该演示只是是获取缩略图,但在另1篇小说中,另多少个小编依照这一个LazyList,又做了3个对峙完整的言传身教(包罗歌曲名称、明星名、时间长度、缩略图等消息),像图 三 所示。

3、网络缓存(三级)

public class NetCacheUtils {

private LocalCacheUtils mLocalCacheUtils;

private MemoryCacheUtils mMemoryCacheUtils;

public NetCacheUtils(MemoryCacheUtils memoryCacheUtils,LocalCacheUtils localCacheUtils) {

mMemoryCacheUtils=memoryCacheUtils;

mLocalCacheUtils=localCacheUtils;

}

获取互联网图片

public void getBitmapFromNet(ImageView imageView,String url){

 new BitmapTask().execute(imageView,url);

}

异步加载互连网图片的里边类

class BitmapTaskextends AsyncTask<Object,Void,Bitmap>{

private ImageView mImageView;

@Override

protected void onPreExecute() { //预操作

super.onPreExecute();

}

@Override

protected Bitmap doInBackground(Object... params) {//耗费时间操作

//依照异步加载时传出的参数顺序来收获参数

mImageView = (ImageView) params[0];

String url = (String) params[1];

//防止网络慢时,控件与加载的图片展现不符(ListView)

mImageView.setTag(url);

//互连网访问

download(url);

return null;

}

@Override

protected void onPostExecute(Bitmap bitmap) {  //后续操作

doInBackground重临的值作为参数字传送入本办法

 if(bitmap!=null){

mImageView.setImageBitmap(bitmap);

String url= (String)mImageView.getTag();

写入本地缓存

mLocalCacheUtils.setLocalCache(url,bitmap);

写入内部存款和储蓄器缓存

 mMemoryCacheUtils.setMemoryCache(url,bitmap);

}

}

}

}


/**

public ImageMemoryCache(Context context) {
    int memClass = ((ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();
    int cacheSize = 1024 * 1024 * memClass / 4;  //硬引用缓存容量,为系统可用内存的1/4
    mLruCache = new LruCache<String, Bitmap>(cacheSize) {
        @Override
        protected int sizeOf(String key, Bitmap value) {
            if (value != null)
                return value.getRowBytes() * value.getHeight();
            else
                return 0;
        }

        @Override
        protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) {
            if (oldValue != null)
                // 硬引用缓存容量满的时候,会根据LRU算法把最近没有被使用的图片转入此软引用缓存
                mSoftCache.put(key, new SoftReference<Bitmap>(oldValue));
        }
    };
    mSoftCache = new LinkedHashMap<String, SoftReference<Bitmap>>(SOFT_CACHE_SIZE, 0.75f, true) {
        private static final long serialVersionUID = 6040103833179403725L;
        @Override
        protected boolean removeEldestEntry(Entry<String, SoftReference<Bitmap>> eldest) {
            if (size() > SOFT_CACHE_SIZE){    
                return true;  
            }  
            return false; 
        }
    };
}

/**
 * 从缓存中获取图片
 */
public Bitmap getBitmapFromCache(String url) {
    Bitmap bitmap;
    //先从硬引用缓存中获取
    synchronized (mLruCache) {
        bitmap = mLruCache.get(url);
        if (bitmap != null) {
            //如果找到的话,把元素移到LinkedHashMap的最前面,从而保证在LRU算法中是最后被删除
            mLruCache.remove(url);
            mLruCache.put(url, bitmap);
            return bitmap;
        }
    }
    //如果硬引用缓存中找不到,到软引用缓存中找
    synchronized (mSoftCache) { 
        SoftReference<Bitmap> bitmapReference = mSoftCache.get(url);
        if (bitmapReference != null) {
            bitmap = bitmapReference.get();
            if (bitmap != null) {
                //将图片移回硬缓存
                mLruCache.put(url, bitmap);
                mSoftCache.remove(url);
                return bitmap;
            } else {
                mSoftCache.remove(url);
            }
        }
    }
    return null;
} 

/**
 * 添加图片到缓存
 */
public void addBitmapToCache(String url, Bitmap bitmap) {
    if (bitmap != null) {
        synchronized (mLruCache) {
            mLruCache.put(url, bitmap);
        }
    }
}

public void clearCache() {
    mSoftCache.clear();
}

环境


  • Windows 2008 R2 64 位
  • Eclipse ADT V22.6.2,Android 4.4.3
  • 三星 SM-G3508,Android OS 4.1

 

4、三级缓存综合采纳

public class BitmapUtils {

private NetCacheUtils mNetCacheUtils;

private LocalCacheUtils mLocalCacheUtils;

private MemoryCacheUtils mMemoryCacheUtils;

public BitmapUtils(){

mMemoryCacheUtils =new MemoryCacheUtils();

mLocalCacheUtils =new LocalCacheUtils();

mNetCacheUtils =new NetCacheUtils(mMemoryCacheUtils,mLocalCacheUtils);

}

  • 从内部存款和储蓄器读取数据速度是最快的,为了越来越大限度使用内部存款和储蓄器,这里运用了两层缓存。 硬引用缓存不会随意被回收,用来保存常用数据,不经常用的转入软引用缓存。

}

示范 LazyList 从网络获取图片并缓存


Github上的示范只有1个 Java 包,但本身再也划分了弹指间,便于明白我的思路。源代码就不贴了,你点击此处下载。

mg4377娱乐手机版 1

图 一 种类结构

  • com.fedorvlasov.lazylist.activity 包是主程序。
  • com.fedorvlasov.lazylist.cache 包,担负缓存,包蕴缓存在外部存款和储蓄器 FileCache 类和内部存款和储蓄器 MemoryCache 类。
  • com.fedorvlasov.lazylist.utils 包,担当流操作。
  • com.fedorvlasov.lazylist.view 包,肩负从网络获取明星专辑的缩略图,并在 ListView 显示,同一时候对缩略图举办缓存。假设缩略图已缓存,则 ListView 从缓存获取并浮现,否则,从互联网得到。 核心部分是,LazyAdapter 类,它继承 BaseAdapter,返回 View,即 ListView 中的每行;ImageLoader 类,负担从网络得到缩略图。

通过先行级加载图片

public void displayBitmap(ImageView imageView,String url){

内部存款和储蓄器缓存

Bitmap bitmap=mMemoryCacheUtils.getMemoryCache(url);

if(bitmap!=null){

imageView.setImageBitmap(bitmap);

return;

}

本地缓存

Bitmap bitmap1=mLocalCacheUtils.getLocalCache(url);

if(bitmap1!=null){

imageView.setImageBitmap(bitmap1);

mMemoryCacheUtils.setMemoryCache(url,bitmap1);

return;

}

网络缓存

mNetCacheUtils.getBitmapFromNet(imageView,url);

}

}


*/

文件缓存类:ImageFileCache
public class ImageFileCache {
private static final String CACHDIR = "ImgCach";
private static final String WHOLESALE_CONV = ".cach";

mg4377娱乐手机版 2

图 二 左:主程序,从网络获取缩略图;右:点击“Clear Cache”清除缓存重新加载

如图 二 左侧所示,是主程序,从互连网获取缩略图并出示。当点击“Clear Cache”开关后,程序会解决缓存,重新加载并呈现缩略图,如图 2右侧所示,有体现出歌唱家缩略图的,还会有没显示出的,没有显示出来的,是正值从网络获取~

mg4377娱乐手机版 3

图 3 网络获得音乐列表

那是另贰个针锋相对完整的以身作则,点击此处下载,那些演示是在 LazyList 基础实现的,但有 bug,程序不太平静,程序的运行不是每一遍都能展现出列表,就算显示出来,缩略图却显得不出去,还没搞领会是怎么回事(老外写的事物,偶然也不太可相信),其中贰个bug 是因为版本异常低,而 Android 4.0 以上的版本不允许在主线程访问网络,你能够尝试,假若弄明白了,麻烦你告诉自身一下~

 

5、Android之四大引用

简单介绍:Java虚拟机存在栈和堆,栈存放变量,堆存放类,它们中间存在1种引用关系

1、强引用:暗许都以强引用,不会回收

2、软引用:当内部存款和储蓄器不足时,垃圾回收器会思虑回收

创建:SoftReference<Bitmap> softReference=new SoftReference<Bitmap>(bitmap);

从软引用中抽出:Bitmap bitmap =softReference.get();

3、弱引用:当内部存款和储蓄器不足时,垃圾回收器更会思量回收,

4、虚引用:当内部存储器不足时,垃圾回收器起首思念回收

5、垃圾:一对从未被引述的对象称之为垃圾

privatestatic finalint SOFT_CACHE_SIZE = 1五;// 软引用缓存容积

private static final int MB = 1024*1024;
private static final int CACHE_SIZE = 10;
private static final int FREE_SD_SPACE_NEEDED_TO_CACHE = 10;

public ImageFileCache() {
    //清理文件缓存
    removeCache(getDirectory());
}

/** 从缓存中获取图片 **/
public Bitmap getImage(final String url) {    
    final String path = getDirectory()   "/"   convertUrlToFileName(url);
    File file = new File(path);
    if (file.exists()) {
        Bitmap bmp = BitmapFactory.decodeFile(path);
        if (bmp == null) {
            file.delete();
        } else {
            updateFileTime(path);
            return bmp;
        }
    }
    return null;
}

/** 将图片存入文件缓存 **/
public void saveBitmap(Bitmap bm, String url) {
    if (bm == null) {
        return;
    }
    //判断sdcard上的空间
    if (FREE_SD_SPACE_NEEDED_TO_CACHE > freeSpaceOnSd()) {
        //SD空间不足
        return;
    }
    String filename = convertUrlToFileName(url);
    String dir = getDirectory();
    File dirFile = new File(dir);
    if (!dirFile.exists())
        dirFile.mkdirs();
    File file = new File(dir  "/"   filename);
    try {
        file.createNewFile();
        OutputStream outStream = new FileOutputStream(file);
        bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
        outStream.flush();
        outStream.close();
    } catch (FileNotFoundException e) {
        Log.w("ImageFileCache", "FileNotFoundException");
    } catch (IOException e) {
        Log.w("ImageFileCache", "IOException");
    }
} 

/**
 * 计算存储目录下的文件大小,
 * 当文件总大小大于规定的CACHE_SIZE或者sdcard剩余空间小于FREE_SD_SPACE_NEEDED_TO_CACHE的规定
 * 那么删除40%最近没有被使用的文件
 */
private boolean removeCache(String dirPath) {
    File dir = new File(dirPath);
    File[] files = dir.listFiles();
    if (files == null) {
        return true;
    }
    if (!android.os.Environment.getExternalStorageState().equals(
            android.os.Environment.MEDIA_MOUNTED)) {
        return false;
    }

    int dirSize = 0;
    for (int i = 0; i < files.length; i  ) {
        if (files[i].getName().contains(WHOLESALE_CONV)) {
            dirSize  = files[i].length();
        }
    }

    if (dirSize > CACHE_SIZE * MB || FREE_SD_SPACE_NEEDED_TO_CACHE > freeSpaceOnSd()) {
        int removeFactor = (int) ((0.4 * files.length)   1);
        Arrays.sort(files, new FileLastModifSort());
        for (int i = 0; i < removeFactor; i  ) {
            if (files[i].getName().contains(WHOLESALE_CONV)) {
                files[i].delete();
            }
        }
    }

    if (freeSpaceOnSd() <= CACHE_SIZE) {
        return false;
    }

    return true;
}

/** 修改文件的最后修改时间 **/
public void updateFileTime(String path) {
    File file = new File(path);
    long newModifiedTime = System.currentTimeMillis();
    file.setLastModified(newModifiedTime);
}

/** 计算sdcard上的剩余空间 **/
private int freeSpaceOnSd() {
    StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
    double sdFreeMB = ((double)stat.getAvailableBlocks() * (double) stat.getBlockSize()) / MB;
    return (int) sdFreeMB;
} 

/** 将url转成文件名 **/
private String convertUrlToFileName(String url) {
    String[] strs = url.split("/");
    return strs[strs.length - 1]   WHOLESALE_CONV;
}

/** 获得缓存目录 **/
private String getDirectory() {
    String dir = getSDPath()   "/"   CACHDIR;
    return dir;
}

/** 取SD卡路径 **/
private String getSDPath() {
    File sdDir = null;
    boolean sdCardExist = Environment.getExternalStorageState().equals(
            android.os.Environment.MEDIA_MOUNTED);  //判断sd卡是否存在
    if (sdCardExist) {
        sdDir = Environment.getExternalStorageDirectory();  //获取根目录
    }
    if (sdDir != null) {
        return sdDir.toString();
    } else {
        return "";
    }
} 

/**
 * 根据文件的最后修改时间进行排序
 */
private class FileLastModifSort implements Comparator<File> {
    public int compare(File arg0, File arg1) {
        if (arg0.lastModified() > arg1.lastModified()) {
            return 1;
        } else if (arg0.lastModified() == arg1.lastModified()) {
            return 0;
        } else {
            return -1;
        }
    }
}

参谋资料


  • Github LazyList
  • androidhive android-custom-listview-with-imgae-and-text
  • androidhive android android-custom-listview-with-image-and-text 译文

 

那五个链接的涉及是,第1个链接的亲自过问是基于第伍个链接达成的,第伍个链接翻译的第一个链接。

 

下载 LazyList Demo

下载 LazyList Demo v.1.1

下载 CompleteLazyList Demo

下载 CompleteLazyList Demo v.2.0

privatestatic LruCache<String, Bitmap> mLruCache; // 硬引用缓存

}

privatestatic LinkedHashMap<String, SoftReference<Bitmap>>mSoftCache; // 软引用缓存

从互连网获取图片:
public class ImageGetFormHttp {
private static final String LOG_TAG = "ImageGetForHttp";

public ImageMemoryCache(Context context) {

public static Bitmap downloadBitmap(String url) {
    final HttpClient client = new DefaultHttpClient();
    final HttpGet getRequest = new HttpGet(url);

    try {
        HttpResponse response = client.execute(getRequest);
        final int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode != HttpStatus.SC_OK) {
            Log.w("ImageDownloader", "Error "   statusCode   " while retrieving bitmap from "   url);
            return null;
        }

        final HttpEntity entity = response.getEntity();
        if (entity != null) {
            InputStream inputStream = null;
            try {
                inputStream = entity.getContent();
                FilterInputStream fit = new FlushedInputStream(inputStream);
                return BitmapFactory.decodeStream(fit);
            } finally {
                if (inputStream != null) {
                    inputStream.close();
                    inputStream = null;
                }
                entity.consumeContent();
            }
        }
    } catch (IOException e) {
        getRequest.abort();
        Log.w(LOG_TAG, "I/O error while retrieving bitmap from "   url, e);
    } catch (IllegalStateException e) {
        getRequest.abort();
        Log.w(LOG_TAG, "Incorrect URL: "   url);
    } catch (Exception e) {
        getRequest.abort();
        Log.w(LOG_TAG, "Error while retrieving bitmap from "   url, e);
    } finally {
        client.getConnectionManager().shutdown();
    }
    return null;
}

/*
 * An InputStream that skips the exact number of bytes provided, unless it reaches EOF.
 */
static class FlushedInputStream extends FilterInputStream {
    public FlushedInputStream(InputStream inputStream) {
        super(inputStream);
    }

    @Override
    public long skip(long n) throws IOException {
        long totalBytesSkipped = 0L;
        while (totalBytesSkipped < n) {
            long bytesSkipped = in.skip(n - totalBytesSkipped);
            if (bytesSkipped == 0L) {
                int b = read();
                if (b < 0) {
                    break;  // we reached EOF
                } else {
                    bytesSkipped = 1; // we read one byte
                }
            }
            totalBytesSkipped  = bytesSkipped;
        }
        return totalBytesSkipped;
    }
}

int memClass = ((ActivityManager) context

}

.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();

终极,获取一张图纸的流水线就像下代码所示:
/*** 获得一张图纸,从多少个地方得到,首先是内部存款和储蓄器缓存,然后是文件缓存,最终从互连网获取 ***/
public Bitmap getBitmap(String url) {
// 从内存缓存中收获图片
Bitmap result;
result = memoryCache.getBitmapFromCache(url);
if (result == null) {
// 文件缓存中猎取
result = fileCache.getImage(url);
if (result == null) {
// 从网络获取
result = ImageGetFormHttp.downloadBitmap(url);
if (result != null) {
fileCache.saveBitmap(result, url);
memoryCache.addBitmapToCache(url, result);
}
} else {
// 增添到内存缓存
memoryCache.addBitmapToCache(url, result);
}
}
return result;
}

int cacheSize = 1024 * 1024 * memClass / 四;// 硬引用缓存体积,为系统可用内部存款和储蓄器的百分之二十五

mLruCache =new LruCache<String, Bitmap>(cacheSize) {

@Override

protectedint sizeOf(String key, Bitmap value) {

if (value !=null)

return value.getRowBytes() * value.getHeight();

else

return 0;

}

@Override

protectedvoid entryRemoved(boolean evicted, String key,

Bitmap oldValue, Bitmap newValue) {

if (oldValue !=null)

// 硬引用缓存容积满的时候,会依附LRU算法把多年来从未被利用的图片转入此软引用缓存

mSoftCache.put(key,new SoftReference<Bitmap>(oldValue));

}

};

mSoftCache =new LinkedHashMap<String, SoftReference<Bitmap>>(

编辑:mg4377娱乐手机版 本文来源:【mg4377娱乐手机版】从网络获取图片并缓存,A

关键词: Android java android网络请求 ListView LazyListVie