本文部分内容来自网络整理,本司不为其真实性负责,如有异议或侵权请及时联系,本司将立即删除!== 本文为word格式,下载后可方便编辑和修改! ==安卓图片批量处理软件篇一:Android_解决图片大量下载:软引用Android 解决图片大量下载:软引用1.对象的强、软、弱和虚引用为了能更加灵活控制对象的生命周期,需要知道对象引用的4中级别,由高到低依次为:强引用、软引用、弱引用和虚引用备注:这四种的区别:⑴强引用(StrongReference)强引用是使用最普遍的引用。
如果一个对象具有强引用,那垃圾回收器绝不会回收它。
当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。
⑵软引用(SoftReference)如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。
只要垃圾回收器没有回收它,该对象就可以被程序使用。
软引用可用来实现内存敏感的高速缓存(下文给出示例)。
软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。
⑶弱引用(WeakReference)弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。
在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。
不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。
弱引用可以和一个引用队列(ReferenceQueue)联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。
⑷虚引用(PhantomReference)“虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。
如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。
虚引用主要用来跟踪对象被垃圾回收器回收的活动。
虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。
当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。
ReferenceQueue queue = new ReferenceQueue ();PhantomReference pr = new PhantomReference (object, queue);程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。
如果程序发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动2.软引用的工作原理和作用如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。
只要垃圾回收器没有回收它,该对象就可以被程序使用。
软引用可用来实现内存敏感的高速缓存,软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。
经典的写法查看:/donglinlucky/article/details/28457773.android 中关于图片大批量的图片下载和内存管理的解决方案思路:(1)根据路径图片进行下载,下载后将图片的保存在imageCache (HashTable)中,并将图片下载到本地;(2)下载到第200张左右以上,应用的内存若出现不足( SoftReference softReference 决定不会oom),android的虚拟机就开始垃圾回收对象,这个时候,获取图片时会出现 SoftReference softReference 获取的图片为null,如果为null,需要根据图片的id和路径去找到已经下载的图片,直接加载显示,如果本地就没有下载过,就直接从网络上下载;可以参考:/kf/201X07/139035.html 将图片加载这个过程封装成一个下载器,专注处理图片下载和缓存问题;这里面的用的是单线程下载,可以使用多线程下载速率更快;代码如下:public Drawable loadDrawable(final String imageUrl, final ImageCallBack imageCallback) {if (imageCache.containsKey(imageUrl)) {SoftReference<Drawable> softReference = imageCache.get(imageUrl);Drawable drawable = softReference.get();if (drawable != null) {return drawable;}}final Handler handler = new Handler() {@Overridepublic void handleMessage(Message message) {imageCallback.imageLoaded((Drawable) message.obj, imageUrl);}};new Thread() {@Overridepublic void run() {Drawable drawable = null;try {drawable = getDrawable(imageUrl);imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));} catch (Exception e) {e.printStackTrace();}Message message = handler.obtainMessage(0, drawable);handler.sendMessage(message);}}.start();return null;}private Drawable getDrawable(String urlString) throws Exception {if(!NetTools.isWifiConnected(context)){getImage = DataPreference.getIsAutoGetPicture(context);}else{getImage = true;}String fileName = urlString.substring(stIndexOf("/") + 1).trim();File cacheFile = null; 极客Androidif(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNT ED)) {//sdcard已挂载 cacheFile = new File(shopPicInSdcard + fileName);if (getImage) {if (!cacheFile.exists() && cacheFile.createNewFile()) {//缓存文件不存在&&创建了该文件,下载缓存图片到SdcardInputStream inputStream = getInputStreamFromHttp(urlString);writeCacheFile2SDCard(cacheFile, readStream(inputStream));}return BitmapDrawable.createFromPath(shopPicInSdcard + fileName);} else {return null;}} else {//只有在没有sdcard的时候才从网上获取数据流if (getImage) {InputStream inputStream = getInputStreamFromHttp(urlString);return Drawable.createFromStream(inputStream, urlString);} else {return null;}}}4.android 在listview getView的时候对图片的处理方式;主要对listview 中的效率优化.篇二:Android批量图片加载经典系列——采用二级缓存、异步加载网络图片(烟台杰瑞教育Android培训部原创)Android批量图片加载经典系列——采用二级缓存、异步加载网络图片Android应用中经常涉及从网络中加载大量图片,为提升加载速度和效率,减少网络流量都会采用二级缓存和异步加载机制,所谓二级缓存就是通过先从内存中获取、再从文件中获取,最后才会访问网络。
内存缓存(一级)本质上是Map集合以key-value对的方式存储图片的url和Bitmap信息,由于内存缓存会造成堆内存泄露,管理相对复杂一些,可采用第三方组件,对于有经验的可自己编写组件,而文件缓存比较简单通常自己封装一下即可。
下面就通过案例看如何实现网络图片加载的优化。
案例新闻的列表图片下面先看看实现一级缓存(内存)、二级缓存(磁盘文件)所编写的组件在内存中存储图片(一级缓存), 采用了1个map来缓存图片代码如下:public class MemoryCache {// 最大的缓存数private static final int MAX_CACHE_CAPACITY = 30;//用Map软引用的Bitmap对象, 保证内存空间足够情况下不会被垃圾回收private HashMap<String, SoftReference<Bitmap>> mCacheMap =new LinkedHashMap<String, SoftReference<Bitmap>>() {private static final long serialVersionUID = 1L;//当缓存数量超过规定大小(返回true)会清除最早放入缓存的protected boolean removeEldestEntry(Map.Entry<String,SoftReference<Bitmap>> eldest){return size() > MAX_CACHE_CAPACITY;};};/*** 从缓存里取出图片* @param id* @return 如果缓存有,并且该图片没被释放,则返回该图片,否则返回null*/public Bitmap get(String id){if(!mCacheMap.containsKey(id)) return null;SoftReference<Bitmap> ref = mCacheMap.get(id);return ref.get();}/*** 将图片加入缓存* @param id* @param bitmap*/public void put(String id, Bitmap bitmap){mCacheMap.put(id, new SoftReference<Bitmap>(bitmap));}/*** 清除所有缓存*/public void clear() {try {for(Map.Entry<String,SoftReference<Bitmap>>entry :mCacheMap.entrySet( )) { SoftReference<Bitmap> sr = entry.getValue();if(null != sr) {Bitmap bmp = sr.get();if(null != bmp) bmp.recycle();}}mCacheMap.clear();} catch (Exception e) {e.printStackTrace();}}}在磁盘中缓存图片(二级缓存),代码如下public class FileCache {//缓存文件目录private File mCacheDir;/*** 创建缓存文件目录,如果有SD卡,则使用SD,如果没有则使用系统自带缓存目录* @param context* @param cacheDir 图片缓存的一级目录*/public FileCache(Context context, File cacheDir, String dir){if(android.os.Environment.getExternalStorageState().equals、(android.os.Environment.MEDIA_MOUNTED))mCacheDir = new File(cacheDir, dir);elsemCacheDir = context.getCacheDir();// 如何获取系统内置的缓存存储路径if(!mCacheDir.exists()) mCacheDir.mkdirs();}public File getFile(String url){File f=null;try {//对url进行编辑,解决中文路径问题String filename = URLEncoder.encode(url,"utf-8");f = new File(mCacheDir, filename);} catch (UnsupportedEncodingException e) {e.printStackTrace();}return f;}public void clear(){//清除缓存文件File[] files = mCacheDir.listFiles();for(File f:files)f.delete();}}android中采用单线程模型即应用运行在UI主线程中,且Android又是实时操作系统要求及时响应否则出现ANR错误,因此对于耗时操作要求不能阻塞UI主线程,需要开启一个线程处理(如本应用中的图片加载)并将线程放入队列中,当运行完成后再通知UI主线程进行更改,同时移除任务——这就是异步任务,在android中实现异步可通过本系列一中所用到的AsyncTask或者使用thread+handler机制,在这里是完全是通过代码编写实现的,这样我们可以更清晰的看到异步通信的实现的本质,代码如下public class AsyncImageLoader{private MemoryCache mMemoryCache;//内存缓存private FileCache mFileCache;//文件缓存private ExecutorService mExecutorService;//线程池//记录已经加载图片的ImageViewprivate Map<ImageView, String> mImageViews = Collections.synchronizedMap(new WeakHashMap<ImageView, String>());//保存正在加载图片的urlprivate List<LoadPhotoTask> mTaskQueue = newArrayList<LoadPhotoTask>(); /*** 默认采用一个大小为5的线程池* @param context* @param memoryCache 所采用的高速缓存* @param fileCache 所采用的文件缓存*/public AsyncImageLoader(Context context, MemoryCache memoryCache, FileCache fileCache) {mMemoryCache = memoryCache;mFileCache = fileCache;mExecutorService = Executors.newFixedThreadPool(5);//建立一个容量为5的固定尺寸的线程池(最大正在运行的线程数量)}/*** 根据url加载相应的图片* @param url* @return 先从一级缓存中取图片有则直接返回,如果没有则异步从文件(二级缓存)中取,如果没有再从网络端获取*/public Bitmap loadBitmap(ImageView imageView, String url) {//先将ImageView记录到Map中,表示该ui已经执行过图片加载了mImageViews.put(imageView, url);Bitmap bitmap = mMemoryCache.get(url);//先从一级缓存中获取图片if(bitmap == null) {enquequeLoadPhoto(url, imageView);//再从二级缓存和网络中获取}return bitmap;}/*** 加入图片下载队列* @param url*/private void enquequeLoadPhoto(String url, ImageView imageView) {//如果任务已经存在,则不重新添加if(isTaskExisted(url))return;LoadPhotoTask task = new LoadPhotoTask(url, imageView);synchronized (mTaskQueue) {mTaskQueue.add(task);//将任务添加到队列中}mExecutorService.execute(task);//向线程池中提交任务,如果没有达到上限(5),则运行否则被阻塞}/*** 判断下载队列中是否已经存在该任务* @param url* @return*/篇三:批量处理相片大小为20K以下的方法更改相片大小为20K以下的方法(图文详解、可以批处理)*如果已经有裁好的一寸相片,用光影魔术手进行批量修改尺寸大小就可以了。