android自带的处理Bitmap out Memory 的处理,我仅仅是改变了些写法成为自己用的东西
每天上万次的启动载入证明这个载入是不错的;
第三方的载入框架非常多,推荐使用成熟框架,比方大家都知道的ImageLoad等,
这里的仅仅供学习;
我也曾在一个菜谱的项目里写过载入手机相冊图片的,只是当时写的不好,有空我会再写一个,这个项目里用这个jar包,上万次的载入偶尔看到三星的报两三个OOM还好
缓存管理在这里
http://blog.csdn.net/intbird/article/details/38338713
图片处理在这里
http://blog.csdn.net/intbird/article/details/38338811
界面回收图片在这里
http://blog.csdn.net/intbird/article/details/19905549
工具Jar包在这里说明:
http://pan.baidu.com/s/1dDtOZbr
集成的一个[缓存和图片资源载入]工具类,BitmapHelper,CacheHelper,,
下载地址http://pan.baidu.com/s/1dDtOZbr
用法://注,必须导入Android-support-v4包.
1,在应用初始化时初始化缓存文件夹:
//(sd下主目录,拍照目录,图片缓存目录)
//主文件夹一般为应用的getString()中的AppName;
CacheHelper.initCache("Intbird");
//经常使用的一些方法
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaW50YmlyZA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
2,初始化图片帮助类
BitmapHelper bitmapHelper=new BitmapHelper(context,R.drawable.ic_launcher,R.drawable.ic_launcher);
BitmapHelper bitmapHelper=new BitmapHelper(context);
//终于载入实现类
BitmapHelper.LoadOptions options=new BitmapHelper.LoadOptions();
//一些简单的图片处理的封装,在其它用到的地方在说明
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaW50YmlyZA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
3 外部帮助类,封装程序中遇到图片的地方
public static class ImageOptions implements Serializable{
public int imageType;
public int cropWidth;
public int cropHeight;
public int displayWidth;
public int displayHeight;
public int qulity;
public int maxKb=-1;
public boolean isNeedRoteAnge=false;
public boolean isTumbnail;
public ImageUploadType uploadType;
public ImageCropType cropType;
//已知载入方法
public LoadBitmapFinish finish;
public DisplayImageOptions displayOption;
public ImageLoadingListener listener;
}
4,普通快捷记载单个图片
bitmapHelper.loadBitmap(BitmapHelper.IMG_TYPE_FILE, fileUrl, iv,options.displayWidth,options.displayHeight,options.finish);
//内部真实实现方式,能够构造这个很多其它的功能
bitmapHelper.loadBitmap(loadOption);
//finish
LoadBitmapFinish 在失败和成功后都会返回,失败时bitmap返回为空
5,对于列表载入实现
//在载入的前面加个true,means is used in listView;
bitmap.loadBitmap(true,BitmapHelper.IMG_TYPE_WEB, value, v,200,200,null);
//内部真实实现方式,能够构造这个很多其它的功能
bitmapHelper.loadBitmap(loadOption);
6,演示样例
//单个
bitmapHelper.loadBitmap(BitmapHelper.IMG_TYPE_FILE, fileUrl, iv,options.displayWidth,options.displayHeight,options.finish);
//列表
@Override
public void setViewImage(ImageView v, String value) {
<span style="white-space:pre"> </span>bitmap.loadBitmap(true,BitmapHelper.IMG_TYPE_WEB, value, v,200,200,null);
}
//停止载入
if(bitmap!=null)
bitmap.finishLoadForList();
}
7,载入效果
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaW50YmlyZA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
1.0.0大致实现方式:版本号已经过多次改动和项目中不同手机收集到的错误信息改动过,请使用云盘上最新的版本号以保证项目能够正常使用(最新的是我在项目里使用的),下面代码仅供学习....
/**
* @author intbird@163.com
* @time 20140606
*/
package com.intbird.utils; import java.lang.ref.WeakReference; import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.ThumbnailUtils;
import android.os.AsyncTask;
import android.widget.ImageView; public class BitmapHelper { private CacheManager cacheManager; public static final int IMG_TYPE_RES=0;
public static final int IMG_TYPE_WEB=1;
public static final int IMG_TYPE_FILE=3; private Bitmap bmpHolder=null;
private Bitmap bmpNoImg=null; public BitmapHelper(Context context,int loadingId,int loadNoId){
cacheManager=CacheManager.getInstance();
bmpHolder=BitmapFactory.decodeResource(context.getResources(),loadingId);
bmpNoImg=BitmapFactory.decodeResource(context.getResources(),loadNoId);
} /**
* 载入图片
* @param type 网络文件,本地文件,还是资源文件
* @param fileUrl url
* @param imageView 控件
* @param width 要获取的指定高度
* @param height 要获取的指定宽度
*/
public void commonLoadBitmap(int type,String fileUrl,ImageView imageView,int width,int height){
//内存和文件里没有图片,又一次获取;
Bitmap bmp=cacheManager.getBitmapFromCache(fileUrl);
if(bmp!=null){
imageView.setImageBitmap(bmp);
}
else{
switch(type){
case IMG_TYPE_WEB:
loadMultiBitmapFromWeb(fileUrl, imageView,width,height);
break;
case IMG_TYPE_FILE:
imageView.setImageBitmap(getBitmapFormFile( fileUrl, width, height, true));
break;
case IMG_TYPE_RES:
imageView.setImageResource(Integer.parseInt(fileUrl));
break;
}
}
} /**
* 设置ImageView为获取指定文件地址的指定高度指定宽度的图片;
* @param fileUrl 文件地址
* @param reqWidth 目标宽度
* @param reqHeight 目标高度
* @return bitmap
*/
public Bitmap loadSingleBitmapFromFile(String fileUrl,ImageView iv,int reqWidth,int reqHeight){
BitmapFactory.Options options=new BitmapFactory.Options();
options.inJustDecodeBounds=true;
options.inSampleSize=calculateInSampleSize(options, reqWidth, reqHeight);
BitmapFactory.decodeFile(fileUrl,options);
options.inJustDecodeBounds=false;
Bitmap bmp=BitmapFactory.decodeFile(fileUrl,options);
if(iv!=null) iv.setImageBitmap(bmp);
return bmp;
}
/**
* 设置ImageView为须要载入的一张网络图片;
* @param webUrl
* @param imageView
* @param width
* @param heigth
*/
public void loadSingleBitmapFromWeb(String webUrl,ImageView imageView,int width,int heigth){
BitmapHelper.BitmapWorkerSingleTask task=new BitmapWorkerSingleTask(imageView);
task.execute(webUrl,width+"",heigth+"");
} /**
* adapter中载入图片
* @param fileUrl 图片地址
* @param imageView 图片控件
* @param width 要得到的宽度
* @param height 要的到的高度
*/
public void loadMultiBitmapFromWeb(String fileUrl, ImageView imageView,int width,int height) { if (cancelPotentialWork(fileUrl, imageView)) { final BitmapMultiWorkerTask task = new BitmapMultiWorkerTask(imageView); final AsyncDrawable asyncDrawable =new AsyncDrawable(bmpHolder, task); imageView.setImageDrawable(asyncDrawable); task.execute(fileUrl,width+"",height+"");
}
} /**
* 从网络中载入一个须要的Bitmap;
* @param webUrl
* @param reqWidth
* @param reqHeight
* @return
*/
public Bitmap getBitmapFormWeb(String webUrl,int reqWidth,int reqHeight){
BitmapFactory.Options options=new BitmapFactory.Options();
options.inJustDecodeBounds=true;
options.inSampleSize=calculateInSampleSize(options, reqWidth, reqHeight);
return ConnInternet.loadBitmapFromNet(webUrl, options);
} /**
* 将图片文件转换成bitmap
*
* @param fileUrl
* 图片文件路径
* @param width
* 宽度
* @param height
* 高度
* @param isThumbnail
* 是否依据高宽生成缩略图
* @return
*/
public Bitmap getBitmapFormFile(String fileUrl, int width, int height,
boolean isThumbnail) {
Bitmap bitmap=loadSingleBitmapFromFile(fileUrl,null, width, height);
// 生成固定尺寸的缩略图
if (isThumbnail) {
bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
}
cacheManager.addBitmapToCache(fileUrl, bitmap);
return bitmap;
} /**
* 转换图片成圆形
*
* @param bitmap
* @return
*/
public static Bitmap changeBitmapToRound(Bitmap bitmap) {
if(bitmap==null)
return null;
int width = bitmap.getWidth();
int height = bitmap.getHeight();
float roundPx;
float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom;
if (width <= height) {
roundPx = width / 2;
left = 0;
top = 0;
right = width;
bottom = width;
height = width;
dst_left = 0;
dst_top = 0;
dst_right = width;
dst_bottom = width;
} else {
roundPx = height / 2;
float clip = (width - height) / 2;
left = clip;
right = width - clip;
top = 0;
bottom = height;
width = height;
dst_left = 0;
dst_top = 0;
dst_right = height;
dst_bottom = height;
} Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888);
Canvas canvas = new Canvas(output); final int color = 0xff424242;
final Paint paint = new Paint();
final Rect src = new Rect((int) left, (int) top, (int) right,
(int) bottom);
final Rect dst = new Rect((int) dst_left, (int) dst_top,
(int) dst_right, (int) dst_bottom);
paint.setAntiAlias(true);// 设置画笔无锯齿 canvas.drawARGB(0, 0, 0, 0); // 填充整个Canvas
paint.setColor(color); // 下面有两种方法画圆,drawRounRect和drawCircle
// canvas.drawRoundRect(rectF, roundPx, roundPx, paint);//
// 画圆角矩形,第一个參数为图形显示区域。第二个參数和第三个參数各自是水平圆角半径和垂直圆角半径。
canvas.drawCircle(roundPx, roundPx, roundPx, paint); paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));// 设置两张图片相交时的模式,參考http://trylovecatch.iteye.com/blog/1189452
canvas.drawBitmap(bitmap, src, dst, paint); // 以Mode.SRC_IN模式合并bitmap和已经draw了的Circle
return output;
} /**
* 计算所需大小的图片 的压缩比例
* @param options
* @param reqWidth 所需宽度
* @param reqHeight 所需高度
* @return 压缩比例
*/
public int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
} /**
* 检查启动的任务
* @param fileUrl 文件路径
* @param imageView 目标控件
* @return 是否開始载入任务
*/
private boolean cancelPotentialWork(String fileUrl, ImageView imageView) { final BitmapMultiWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); if (bitmapWorkerTask != null) { String bitmapUrl = bitmapWorkerTask.fileUrl;
if (bitmapUrl!=null&&bitmapUrl != fileUrl) { bitmapWorkerTask.cancel(true);
return true;
} else {
return false;
}
}
return true;
} /**
* 获取该图片控件中的载入任务
* @param imageView
* @return 返回该任务
*/
private BitmapMultiWorkerTask getBitmapWorkerTask(ImageView imageView) {
if (imageView != null) {
final Drawable drawable = imageView.getDrawable();
if (drawable instanceof AsyncDrawable) {
final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
return asyncDrawable.getBitmapWorkerTask();
}
}
return null;
}
private class AsyncDrawable extends BitmapDrawable {
private final WeakReference<BitmapMultiWorkerTask> bitmapWorkerTaskReference;
@SuppressWarnings("deprecation")
public AsyncDrawable(Bitmap bitmap,BitmapMultiWorkerTask bitmapWorkerTask) {
super(bitmap);
bitmapWorkerTaskReference =new WeakReference<BitmapMultiWorkerTask>(bitmapWorkerTask);
}
public BitmapMultiWorkerTask getBitmapWorkerTask() {
return bitmapWorkerTaskReference.get();
}
}
private class BitmapMultiWorkerTask extends AsyncTask<String, Void, Bitmap> {
private WeakReference<ImageView> imageViewReference;
private String fileUrl;
public BitmapMultiWorkerTask(ImageView imageView){
imageViewReference=new WeakReference<ImageView>(imageView);
}
@Override
protected Bitmap doInBackground(String... params) {
fileUrl=params[0];
int reqWidth=Integer.valueOf(params[1]);
int reqHeight=Integer.valueOf(params[2]);
Bitmap bitmap=getBitmapFormWeb(fileUrl,reqWidth,reqHeight);
return bitmap;
} @Override
protected void onPostExecute(Bitmap bitmap) { if (isCancelled()) {
bitmap = null;
} if (imageViewReference != null) {
final ImageView imageView = imageViewReference.get(); final BitmapMultiWorkerTask bitmapWorkerTask =getBitmapWorkerTask(imageView); if (this == bitmapWorkerTask && imageView != null) { if(bitmap!=null){
imageView.setImageBitmap(bitmap);
cacheManager.addBitmapToCache(fileUrl, bitmap);
} else{
imageView.setImageBitmap(bmpNoImg);
}
}
}
}
}
/**
* 异步载入一张图片
* @author intbird@163.com
*
*/
private class BitmapWorkerSingleTask extends AsyncTask<String, Void, Bitmap>{
private WeakReference<ImageView> imageViewReference;
private String fileUrl="";
public BitmapWorkerSingleTask(ImageView imageView){
imageViewReference=new WeakReference<ImageView>(imageView);
}
@Override
protected Bitmap doInBackground(String... params) {
fileUrl=params[0];
int reqWidth=Integer.valueOf(params[1]);
int reqHeight=Integer.valueOf(params[2]);
Bitmap bitmap=getBitmapFormWeb(fileUrl,reqWidth,reqHeight);
return bitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
if(bitmap!=null){
imageView.setImageBitmap(bitmap);
}
else{
imageView.setImageBitmap(bmpNoImg);
}
}
}
}
}
}
android自带的处理Bitmap out Memory 的处理,我仅仅是改变了些写法成为自己用的东西的更多相关文章
- 记一次使用 android 自带 WebView 做富文本编辑器之API、机型的兼容及各种奇葩bug的解决
转载请声明出处(http://www.cnblogs.com/linguanh/) 目录 1,测试设备介绍 2,开源项目richeditor及CrossWalk的选择 3,遇到的bug及其解决方法 4 ...
- Android 自带图标库 android.R.drawable
在xml文件中调用. android:title="@string/secure_connect"android:orderInCategory="100"an ...
- 删除Android自带软件方法及adb remount 失败解决方案
删除Android自带软件方法 1.在电脑上打开cmd,然后输入命令 adb remount adb shell su 2.接着就是Linux命令行模式了,输入 cd system/app 3然后输入 ...
- Android开发优化之——对Bitmap的内存优化
http://blog.csdn.net/arui319/article/details/7953690 在Android应用里,最耗费内存的就是图片资源.而且在Android系统中,读取位图Bitm ...
- 解决android自带textview右侧文字不能对齐的问题
package com.sixin.view; import android.content.Context; import android.graphics.Canvas; import andro ...
- 调用Android自带日历功能(日历列表单、添加一个日历事件)
调用Android自带日历功能 觉得这篇文章不错,转载过来. 转载:http://blog.csdn.net/djy1992/article/details/9948393 Android手机配备有 ...
- Android有效的治疗方法Bitmap,减少内存
Android有效的治疗方法Bitmap,减少内存 照片可能有不同的大小. 在很多情况下,大小.比如,我们的Camera应用,我们所拍的照片的大小远大于屏幕显示的大小 假如你的应用被限制了内存使用,显 ...
- Android自带Monkey测试
Monkey是在模拟器上或设备上运行的一个小程序,它能够产生为随机的用户事件流,例如点击(click),触摸(touch),挥手(gestures),还有一系列的系统级事件.可以使用Monkey来给正 ...
- 采用busybox 代替android 自带的shell
折腾了几天,被Android那点儿少得可怜的shell命令折磨的死去活来,终于下定了革命的决心.看一下怎么把渺小的toolbox替换成伟大的busybox吧.先大致描述一下Android系统中的she ...
随机推荐
- IOS开发之Swift学习笔记
1.因为存储属性要求初始化,我们可以使用lazy修饰符来延迟初始化.
- unity多语言本地化
简介 嗯...一般来说做游戏啥的都不会只发一个国家,但是每个国家语言不同,就存在多语言本地化的问题,然后直接用过一个通过xml完成本地化的东东,然后策划反馈不会修改xml,扔给我一个excel让我自己 ...
- 【PostgreSQL-9.6.3】触发器概述(普通触发器)
一个触发器声明了当执行一种特定类型的操作时数据库应该自动执行一个特殊的函数.触发器可以被附加到表.视图和外部表.触发器经常用于做完整性约束,或者某种业务规则的约束. 1. 触发器的创建语法如下: CR ...
- CSS——padding
padding是盒子内容与边框的距离. padding:10px;/*上下左右都是10px*/ padding:10px 20px;/*上下是10px 左右是20px*/ padding:10px 2 ...
- 【译】x86程序员手册07 - 2.5操作数选择
2.5 Operand Selection 操作数选择 An instruction can act on zero or more operands, which are the data mani ...
- 从JavaScript的单线程执行说起
先看一段代码: 1 2 3 4 5 setTimeout(function(){ alert("a"); }, 0); while(1); alert("b&qu ...
- Luogu 2951 捉迷藏Hide and Seek
P2951 [USACO09OPEN]捉迷藏Hide and Seek 题目描述 Bessie is playing hide and seek (a game in which a number o ...
- Python之类方法,lambda,闭包简谈
类方法,lambda,闭包 类方法 lambda 闭包 类方法 classmethod staticmethod instancemethod 类方法 类方法,通过装饰器@classmethod来标明 ...
- Codeforces 919C - Seat Arrangements
传送门:http://codeforces.com/contest/919/problem/C 给出一张n×m的座位表(有已占座位和空座位),请选择同一行(或列)内连续的k个座位.求选择的方法数. H ...
- JSTL 实现 为Select赋多个值
需要注意需要在.jsp文件中引入相应的类库 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core ...