android 加载长图到底可以加载多大的图不报OOM错误

Android 高效加载大图片避免OOM
参考链接:http://blog.csdn.net/coderinchina/article/details/
我们项目中经常会加载图片,有时候如果加载图片过多的话,小则导致程序很卡,重则OOM导致App挂了,今天翻译https://developer.android.com/training/displaying-bitmaps/index.html,学习Google高效加载大图片的方法。
图片有各种形状和大小,但在大多数情况下,这些图片都会大于我们程序所需要的大小。比如说系统图片库里展示的图片大都是用手机摄像头拍出来的,这些图片的分辨率会比我们手机屏幕的分辨率高得多。大家应该知道,我们编写的应用程序都是有一定内存限制的,程序占用了过高的内存就容易出现OOM(OutOfMemory)异常。我们可以通过下面的代码看出每个应用程序最高可用内存是多少。
现在大部分手机都是32M,既然知道了每个app分配的内存,所以就要计算好加载多少图片而不导致出现OOM,所以要计算每张图片所占用的内存是多少。
Android中计算一张图片所占内存大小方法:图片长*宽*所占像素字节数,而像素字节数Android中也就四种,
1:ALPHA_8 占1个字节
2:ARGB_4444 占2个字节
3:ARGB_8888 占4个字节
4:RGB_565
注:ARGB指的是一种色彩模式,里面A代表Alpha,R表示red,G表示green,B表示blue,其实所有的可见色都是红绿蓝组成的,所以红绿蓝又称为三原色。
A  R  G  B透明度 红色 绿色 蓝色
而这些字节数是可以通过bitmap对象去设置的,bitmap.setConfig(Bitmap.Config.ARGB_4444);如果这是个定值,那么要改变一个张图片的大小,就只能改宽或者高了,如果只改高,宽不变的话,就会造成图片变形,因此一般都是一起改动,所以图片要缩放,而缩放时根据屏幕的宽和高来缩放的,因为Android设备很多,每个屏幕的宽和高也不一样,这样就能达到加载大图片避免OOM。
比如一张480*800的图片直接加载到内存中,如果图片很多那就很容易造成OOM,那就必须压缩,比如按1/8进行压缩,压缩后得到的60*100,如果从服务器获取的图片规格不一样,那压缩后现在在ImageView上肯定不一样,因为ImageView宽和高肯定是设置成wrap_content。
现在写个Demo缩放图片代码如下
计算缩放比例一般有2种做法:
1:根据屏幕宽和高来缩放图片
2:根据要缩放后的宽和高来缩放,上面的例子就是根据这种。
没有更多推荐了,
不良信息举报
举报内容:
Android 高效加载大图片避免OOM
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!项目用到加载大图片,app老是出现OOM异常,总结了几点经验,供参考。
1、手动干涉dalvik的堆内存处理效率:
private final static float TARGET_HEAP_UTILIZATION = 0.75f;
//for same activity
public void onCreate()
VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION);
2、手动指定Android堆大小:
private final static int CWJ_HEAP_SIZE = 6*
//for same activity
public void onCreate()
VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE); //设置最小heap内存为6MB大小。当然对于内存吃紧来说还可以通过手动干涉GC去处理
3、手动指定回收内存,指定gc:
if(bitmap!=null && !bitmap.isRecycled())
bitmap.recycle();
System.gc();
4、图片必须进行缩放,不然多半会出OOM:
* @param url
* @param sc
,显示的像素大小
* @return 返回指定RUL的缩略图
* @author jevan
public static Bitmap loadImageFromUrl(String url, int sc)
InputStream i = null;
BufferedInputStream bis = null;
ByteArrayOutputStream out = null;
if (url == null)
return null;
m = new URL(url);
i = (InputStream) m.getContent();
bis = new BufferedInputStream(i, 1024 * 4);
out = new ByteArrayOutputStream();
int len = 0;
while ((len = bis.read(isBuffer)) != -1)
out.write(isBuffer, 0, len);
out.close();
bis.close();
} catch (MalformedURLException e1)
e1.printStackTrace();
return null;
} catch (IOException e)
e.printStackTrace();
if (out == null)
return null;
byte[] data = out.toByteArray();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(data, 0, data.length, options);
options.inJustDecodeBounds = false;
int be = (int) (options.outHeight / (float) sc);
if (be &= 0)
} else if (be & 3)
options.inSampleSize =
Bitmap bmp =null;
bmp = BitmapFactory.decodeByteArray(data, 0, data.length, options); //返回缩略图
} catch (OutOfMemoryError e)
// TODO: handle exception
MainActivity.print("Tile Loader (241) Out Of Memory Error " + e.getLocalizedMessage());
System.gc();
bmp =null;
把上面几条全部用上,OOM的异常基本上能完全避免!!!
以下内容为转载,收藏。
//我们在BitmapManager.instance().decodeFile对图片进行解码,生成Bitmap的时候,我们会发现很多大图片会报OutOfMemoryError的错误,这个时候我们需要改变options里面的一些参数来解决这个问题,不然我们程序就跑不下去了。最简单的方法就是改变options.inSampleSize这个参数,把它增大,就可以解决很多图片OutOfMemoryError的问题。
//下面是一个使用了这个方式的代码
public static Bitmap makeBitmap(String path, int minSideLength, int maxNumOfPixels, BitmapFactory.Options options)
Bitmap b = null;
Log.i(TAG, "makeBitmap : path = " + path);
if (path == null)
return null;
File f = new File(path);
// b = BitmapManager.instance().decodeFile(f, null);
//} catch (OutOfMemoryError ex) {
// Log.e(TAG, "Got oom exception, we may try one more time, using Options:" + ex.getMessage());
if (options == null)
options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapManager.instance().decodeFile(f, options);
if (options.mCancel || options.outWidth == -1 || options.outHeight == -1)
return null;
options.inSampleSize = computeSampleSize(options, minSideLength, maxNumOfPixels);
options.inJustDecodeBounds = false;
options.inDither = true;
options.inPreferredConfig = null;//Bitmap.Config.ARGB_8888;
b = BitmapManager.instance().decodeFile(f, options);
} catch (OutOfMemoryError ex2)
Log.e(TAG, "Got oom exception when retry the 2nd time,options.inSampleSize= " + options.inSampleSize + " minSideLength = "
+ minSideLength + " maxNumOfPixels =" + maxNumOfPixels, ex2);
options.inSampleSize += 1;
options.inJustDecodeBounds = false;
options.inDither = true;
options.inPreferredConfig = null;
b = BitmapManager.instance().decodeFile(f, options);
} catch (OutOfMemoryError e)
Log.e(TAG, "Got oom exception when retry the 2nd time,options.inSampleSize= " + options.inSampleSize + " minSideLength = "
+ minSideLength + " maxNumOfPixels =" + maxNumOfPixels, e);
options.inSampleSize += 1;
options.inJustDecodeBounds = false;
options.inDither = true;
options.inPreferredConfig = null;
b = BitmapManager.instance().decodeFile(f, options);
} catch (OutOfMemoryError ex)
Log.e(TAG, "Got oom exception when retry the 2nd time,options.inSampleSize= " + options.inSampleSize
+ " minSideLength = " + minSideLength + " maxNumOfPixels =" + maxNumOfPixels, ex);
return null;
//另外一处代码
public static Bitmap getBitpMap(InputStream is)
ParcelFileD
pfd = getContentResolver().openFileDescriptor(uri, "r");
} catch (IOException ex)
return null;
java.io.FileDescriptor fd = pfd.getFileDescriptor();
BitmapFactory.Options options = new BitmapFactory.Options();
//先指定原始大小
options.inSampleSize = 1;
//只进行大小判断
options.inJustDecodeBounds = true;
//调用此方法得到options得到图片的大小
BitmapFactory.decodeFileDescriptor(fd, null, options);
//BitmapFactory.decodeStream(is, null, options);
//我们的目标是在800pixel的画面上显示。
//所以需要调用computeSampleSize得到图片缩放的比例
options.inSampleSize = computeSampleSize(options, 800);
//OK,我们得到了缩放的比例,现在开始正式读入BitMap数据
options.inJustDecodeBounds = false;
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
//根据options参数,减少所需要的内存
Bitmap sourceBitmap = BitmapFactory.decodeFileDescriptor(fd, null, options);
Bitmap sourceBitmap = BitmapFactory.decodeStream(is, null, options);
return sourceB
//这个函数会对图片的大小进行判断,并得到合适的缩放比例,比如2即1/2,3即1/3
static int computeSampleSize(BitmapFactory.Options options, int target)
int w = options.outW
int h = options.outH
int candidateW = w /
int candidateH = h /
int candidate = Math.max(candidateW, candidateH);
if (candidate == 0)
if (candidate & 1)
if ((w & target) && (w / candidate) & target)
candidate -= 1;
if (candidate & 1)
if ((h & target) && (h / candidate) & target)
candidate -= 1;
//if (VERBOSE)
Log.v(TAG, "for w/h " + w + "/" + h + " returning " + candidate + "(" + (w / candidate) + " / " + (h / candidate));
阅读(...) 评论()& & &在最近做的工程中发现加载的图片太多或图片过大时经常出现OOM问题,找网上资料也提供了很多方法,但自己感觉有点乱,特此,今天在不同型号的三款安卓手机上做了测试,因为有效果也有结果,今天小马就做个详细的总结,以供朋友们共同交流学习,也供自己以后在解决OOM问题上有所提高,提前讲下,片幅有点长,涉及的东西太多,大家耐心看,肯定有收获的,里面的很多东西小马也是学习参考网络资料使用的,先来简单讲下下:
& &一般我们大家在遇到内存问题的时候常用的方式网上也有相关资料,大体如下几种:
& &一:在内存引用上做些处理,常用的有软引用、强化引用、弱引用
& &二:在内存中加载图片时直接在内存中做处理,如:边界压缩
& &三:动态回收内存
& &四:优化Dalvik虚拟机的堆内存分配
& &五:自定义堆内存大小
& &可是真的有这么简单吗,就用以上方式就能解决OOM了?不是的,继续来看...
& &下面小马就照着上面的次序来整理下解决的几种方式,数字序号与上面对应:
& &1:软引用(SoftReference)、虚引用(PhantomRefrence)、弱引用(WeakReference),这三个类是对heap中java对象的应用,通过这个三个类可以和gc做简单的交互,除了这三个以外还有一个是最常用的强引用
& & 1.1:强引用,例如下面代码:
Object&o=new&Object();&&&&&&&
Object&o1=o;&&&
& & &上面代码中第一句是在heap堆中创建新的Object对象通过o引用这个对象,第二句是通过o建立o1到new Object()这个heap堆中的对象的引用,这两个引用都是强引用.只要存在对heap中对象的引用,gc就不会收集该对象.如果通过如下代码:
o=null;&&&&&&&
& & & heap中对象有强可及对象、软可及对象、弱可及对象、虚可及对象和不可到达对象。应用的强弱顺序是强、软、弱、和虚。对于对象是属于哪种可及的对象,由他的最强的引用决定。如下:
String&abc=new&String("abc");&&&
SoftReference&String&&abcSoftRef=new&SoftReference&String&(abc);&&&
WeakReference&String&&abcWeakRef&=&new&WeakReference&String&(abc);&&
abc=null;&&
abcSoftRef.clear();&
上面的代码中:
& & 第一行在heap对中创建内容为&abc&的对象,并建立abc到该对象的强引用,该对象是强可及的。第二行和第三行分别建立对heap中对象的软引用和弱引用,此时heap中的对象仍是强可及的。第四行之后heap中对象不再是强可及的,变成软可及的。同样第五行执行之后变成弱可及的。
& & & &&1.2:软引用
& & & & & & & &软引用是主要用于内存敏感的高速缓存。在jvm报告内存不足之前会清除所有的软引用,这样以来gc就有可能收集软可及的对象,可能解决内存吃紧问题,避免内存溢出。什么时候会被收集取决于gc的算法和gc运行时可用内存的大小。当gc决定要收集软引用是执行以下过程,以上面的abcSoftRef为例:
& & 1 首先将abcSoftRef的referent设置为null,不再引用heap中的new String("abc")对象。
& & 2 将heap中的new String("abc")对象设置为可结束的(finalizable)。
& & 3 当heap中的new String("abc")对象的finalize()方法被运行而且该对象占用的内存被释放, abcSoftRef被添加到它的ReferenceQueue中。
& &注:对ReferenceQueue软引用和弱引用可以有可无,但是虚引用必须有,参见:
Reference(T&paramT,&ReferenceQueue&?&super&T&paramReferenceQueue)&&
& & & & &被 Soft Reference 指到的对象,即使没有任何 Direct Reference,也不会被清除。一直要到 JVM 内存不足且 没有 Direct Reference 时才会清除,SoftReference 是用来设计 object-cache 之用的。如此一来 SoftReference 不但可以把对象 cache 起来,也不会造成内存不足的错误 (OutOfMemoryError)。我觉得 Soft Reference 也适合拿来实作 pooling 的技巧。&
&A&obj&=&new&A();&&&&
Refenrence&sr&=&new&SoftReference(obj);&&&&
if(sr!=null){&&&&
&&&&obj&=&sr.get();&&&&
}else{&&&&
&&&&obj&=&new&A();&&&&
&&&&sr&=&new&SoftReference(obj);&&&&
& & 1.3:弱引用
& & & & & & & &&当gc碰到弱可及对象,并释放abcWeakRef的引用,收集该对象。但是gc可能需要对此运用才能找到该弱可及对象。通过如下代码可以了明了的看出它的作用:
String&abc=new&String("abc");&&&&&&&
WeakReference&String&&abcWeakRef&=&new&WeakReference&String&(abc);&&&&&&&
abc=null;&&&&&&&
System.out.println("before&gc:&"+abcWeakRef.get());&&&&&&&
System.gc();&&&&&&&
System.out.println("after&gc:&"+abcWeakRef.get());&&&&
运行结果: & &
before gc: abc & &
after gc: null &&
& & &gc收集弱可及对象的执行过程和软可及一样,只是gc不会根据内存情况来决定是不是收集该对象。如果你希望能随时取得某对象的信息,但又不想影响此对象的垃圾收集,那么你应该用 Weak Reference 来记住此对象,而不是用一般的 reference。& &
A&obj&=&new&A();&&&&
&&&&WeakReference&wr&=&new&WeakReference(obj);&&&&
&&&&obj&=&null;&&&&
  ...&&&&
  if&(wr.get()==null)&{&&&&
  System.out.println("obj&已经被清除了&");&&&&
  }&else&{&&&&
  System.out.println("obj&尚未被清除,其信息是&"+obj.toString());&&&
  ...&&&
& & 在此例中,透过 get() 可以取得此 Reference 的所指到的对象,如果返回值为 null 的话,代表此对象已经被清除。这类的技巧,在设计 Optimizer 或 Debugger 这类的程序时常会用到,因为这类程序需要取得某对象的信息,但是不可以 影响此对象的垃圾收集。
& & &1.4:虚引用
& & &就是没有的意思,建立虚引用之后通过get方法返回结果始终为null,通过源代码你会发现,虚引用通向会把引用的对象写进referent,只是get方法返回结果为null.先看一下和gc交互的过程在说一下他的作用.&
& & & 1.4.1 不把referent设置为null, 直接把heap中的new String("abc")对象设置为可结束的(finalizable).
& & & 1.4.2 与软引用和弱引用不同, 先把PhantomRefrence对象添加到它的ReferenceQueue中.然后在释放虚可及的对象.&
& &你会发现在收集heap中的new String("abc")对象之前,你就可以做一些其他的事情.通过以下代码可以了解他的作用.
import&java.lang.ref.PhantomR&&&&&&&
import&java.lang.ref.R&&&&&&&
import&java.lang.ref.ReferenceQ&&&&&&&
import&java.lang.reflect.F&&&&&&&
public&class&Test&{&&&&&&&
&&&&public&static&boolean&isRun&=&true;&&&&&&&
&&&&public&static&void&main(String[]&args)&throws&Exception&{&&&&&&&
&&&&&&&&String&abc&=&new&String("abc");&&&&&&&
&&&&&&&&System.out.println(abc.getClass()&+&"@"&+&abc.hashCode());&&&&&&&
&&&&&&&&final&ReferenceQueue&referenceQueue&=&new&ReferenceQueue&String&();&&&&&&&
&&&&&&&&new&Thread()&{&&&&&&&
&&&&&&&&&&&&public&void&run()&{&&&&&&&
&&&&&&&&&&&&&&&&while&(isRun)&{&&&&&&&
&&&&&&&&&&&&&&&&&&&&Object&o&=&referenceQueue.poll();&&&&&&&
&&&&&&&&&&&&&&&&&&&&if&(o&!=&null)&{&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&try&{&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&Field&rereferent&=&Reference.class&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&.getDeclaredField("referent");&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&rereferent.setAccessible(true);&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&Object&result&=&rereferent.get(o);&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&System.out.println("gc&will&collect:"&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&+&result.getClass()&+&"@"&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&+&result.hashCode());&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&}&catch&(Exception&e)&{&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&e.printStackTrace();&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&
&&&&&&&&&&&&&&&&&&&&}&&&&&&&
&&&&&&&&&&&&&&&&}&&&&&&&
&&&&&&&&&&&&}&&&&&&&
&&&&&&&&}.start();&&&&&&&
&&&&&&&&PhantomReference&String&&abcWeakRef&=&new&PhantomReference&String&(abc,&&&&&&&
&&&&&&&&&&&&&&&&referenceQueue);&&&&&&&
&&&&&&&&abc&=&null;&&&&&&&
&&&&&&&&Thread.currentThread().sleep(3000);&&&&&&&
&&&&&&&&System.gc();&&&&&&&
&&&&&&&&Thread.currentThread().sleep(3000);&&&&&&&
&&&&&&&&isRun&=&false;&&&&&&&
&&&&}&&&&&&&
class java.lang.String@96354 &&
gc will collect:class java.lang.String@96354 &好了,关于引用就讲到这,下面看2
& &2:在内存中压缩小马做了下测试,对于少量不太大的图片这种方式可行,但太多而又大的图片小马用个笨的方式就是,先在内存中压缩,再用软引用避免OOM,两种方式代码如下,大家可参考下:
& & &方式一代码如下:
@SuppressWarnings("unused")&
private&Bitmap&copressImage(String&imgPath){&
&&&&File&picture&=&new&File(imgPath);&
&&&&Options&bitmapFactoryOptions&=&new&BitmapFactory.Options();&
&&&&bitmapFactoryOptions.inJustDecodeBounds&=&true;&
&&&&bitmapFactoryOptions.inSampleSize&=&2;&
&&&&int&outWidth&&=&bitmapFactoryOptions.outW&
&&&&int&outHeight&=&bitmapFactoryOptions.outH&
&&&&bmap&=&BitmapFactory.decodeFile(picture.getAbsolutePath(),&
&&&&&&&&&bitmapFactoryOptions);&
&&&&float&imagew&=&150;&
&&&&float&imageh&=&150;&
&&&&int&yRatio&=&(int)&Math.ceil(bitmapFactoryOptions.outHeight&
&&&&&&&&&&&&/&imageh);&
&&&&int&xRatio&=&(int)&Math&
&&&&&&&&&&&&.ceil(bitmapFactoryOptions.outWidth&/&imagew);&
&&&&if&(yRatio&&&1&||&xRatio&&&1)&{&
&&&&&&&&if&(yRatio&&&xRatio)&{&
&&&&&&&&&&&&bitmapFactoryOptions.inSampleSize&=&yR&
&&&&&&&&}&else&{&
&&&&&&&&&&&&bitmapFactoryOptions.inSampleSize&=&xR&
&&&&&&&&}&
&&&&bitmapFactoryOptions.inJustDecodeBounds&=&false;&
&&&&bmap&=&BitmapFactory.decodeFile(picture.getAbsolutePath(),&
&&&&&&&&&&&&bitmapFactoryOptions);&
&&&&if(bmap&!=&null){&&&&&&&&&&&&&&&&
&&&&&&&&return&&
&&&&return&null;&
& & &方式二代码如下:
package&com.lvguo.scanstreet.&
import&java.io.F&
import&java.lang.ref.SoftR&
import&java.util.ArrayL&
import&java.util.HashM&
import&java.util.L&
import&android.app.A&
import&android.app.AlertD&
import&android.content.C&
import&android.content.DialogI&
import&android.content.I&
import&android.content.res.TypedA&
import&android.graphics.B&
import&android.graphics.BitmapF&
import&android.graphics.BitmapFactory.O&
import&android.os.B&
import&android.view.V&
import&android.view.ViewG&
import&android.view.WindowM&
import&android.widget.AdapterV&
import&android.widget.AdapterView.OnItemLongClickL&
import&android.widget.BaseA&
import&android.widget.G&
import&android.widget.ImageV&
import&android.widget.T&
import&com.lvguo.scanstreet.R;&
import&com.lvguo.scanstreet.data.ApplicationD&
public&class&PhotoScanActivity&extends&Activity&{&
&&&&private&Gallery&gallery&;&
&&&&private&List&String&&ImageL&
&&&&private&List&String&&it&;&
&&&&private&ImageAdapter&adapter&;&&
&&&&private&String&path&;&
&&&&private&String&shopT&
&&&&private&HashMap&String,&SoftReference&Bitmap&&&imageCache&=&null;&
&&&&private&Bitmap&bitmap&=&null;&
&&&&private&SoftReference&Bitmap&&srf&=&null;&
&&&&@Override&
&&&&public&void&onCreate(Bundle&savedInstanceState)&{&
&&&&&&&&super.onCreate(savedInstanceState);&
&&&&&&&&getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,&&
&&&&&&&&WindowManager.LayoutParams.FLAG_FULLSCREEN);&&
&&&&&&&&setContentView(R.layout.photoscan);&
&&&&&&&&Intent&intent&=&this.getIntent();&
&&&&&&&&if(intent&!=&null){&
&&&&&&&&&&&&if(intent.getBundleExtra("bundle")&!=&null){&
&&&&&&&&&&&&&&&&Bundle&bundle&=&intent.getBundleExtra("bundle");&
&&&&&&&&&&&&&&&&path&=&bundle.getString("path");&
&&&&&&&&&&&&&&&&shopType&=&bundle.getString("shopType");&
&&&&&&&&&&&&}&
&&&&&&&&}&
&&&&&&&&init();&
&&&&private&void&init(){&
&&&&&&&&imageCache&=&new&HashMap&String,&SoftReference&Bitmap&&();&
&&&&&&&&&gallery&=&(Gallery)findViewById(R.id.gallery);&
&&&&&&&&&ImageList&=&getSD();&
&&&&&&&&&if(ImageList.size()&==&0){&
&&&&&&&&&&&&Toast.makeText(getApplicationContext(),&"无照片,请返回拍照后再使用预览",&Toast.LENGTH_SHORT).show();&
&&&&&&&&&&&&return&;&
&&&&&&&&&}&
&&&&&&&&&adapter&=&new&ImageAdapter(this,&ImageList);&
&&&&&&&&&gallery.setAdapter(adapter);&
&&&&&&&&&gallery.setOnItemLongClickListener(longlistener);&
&&&&private&OnItemLongClickListener&longlistener&=&new&OnItemLongClickListener()&{&
&&&&&&&&@Override&
&&&&&&&&public&boolean&onItemLongClick(AdapterView&?&&parent,&View&view,&
&&&&&&&&&&&&&&&&final&int&position,&long&id)&{&
&&&&&&&&&&&&&
&&&&&&&&&&&&AlertDialog.Builder&dialog&=&new&AlertDialog.Builder(PhotoScanActivity.this);&
&&&&&&&&&&&&dialog.setIcon(R.drawable.warn);&
&&&&&&&&&&&&dialog.setTitle("删除提示");&
&&&&&&&&&&&&dialog.setMessage("你确定要删除这张照片吗?");&
&&&&&&&&&&&&dialog.setPositiveButton("确定",&new&DialogInterface.OnClickListener()&{&
&&&&&&&&&&&&&&&&@Override&
&&&&&&&&&&&&&&&&public&void&onClick(DialogInterface&dialog,&int&which)&{&
&&&&&&&&&&&&&&&&&&&&File&file&=&new&File(it.get(position));&
&&&&&&&&&&&&&&&&&&&&boolean&isS&
&&&&&&&&&&&&&&&&&&&&if(file.exists()){&
&&&&&&&&&&&&&&&&&&&&&&&&isSuccess&=&file.delete();&
&&&&&&&&&&&&&&&&&&&&&&&&if(isSuccess){&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&ImageList.remove(position);&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&adapter.notifyDataSetChanged();&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&if(ImageList.size()&==&0){&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&Toast.makeText(getApplicationContext(),&getResources().getString(R.string.phoSizeZero),&Toast.LENGTH_SHORT).show();&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&}&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&Toast.makeText(getApplicationContext(),&getResources().getString(R.string.phoDelSuccess),&Toast.LENGTH_SHORT).show();&
&&&&&&&&&&&&&&&&&&&&&&&&}&
&&&&&&&&&&&&&&&&&&&&}&
&&&&&&&&&&&&&&&&}&
&&&&&&&&&&&&});&
&&&&&&&&&&&&dialog.setNegativeButton("取消",new&DialogInterface.OnClickListener()&{&
&&&&&&&&&&&&&&&&@Override&
&&&&&&&&&&&&&&&&public&void&onClick(DialogInterface&dialog,&int&which)&{&
&&&&&&&&&&&&&&&&&&&&dialog.dismiss();&
&&&&&&&&&&&&&&&&}&
&&&&&&&&&&&&});&
&&&&&&&&&&&&dialog.create().show();&
&&&&&&&&&&&&return&false;&
&&&&&&&&}&
&&&&private&List&String&&getSD()&{&
&&&&&&&&File&fileK&;&
&&&&&&&&it&=&new&ArrayList&String&();&
&&&&&&&&if("newadd".equals(shopType)){&&
&&&&&&&&&&&&&&
&&&&&&&&&&&&fileK&=&new&File(ApplicationData.TEMP);&
&&&&&&&&}else{&
&&&&&&&&&&&&&
&&&&&&&&&&&&fileK&=&new&File(path);&
&&&&&&&&}&
&&&&&&&&File[]&files&=&fileK.listFiles();&
&&&&&&&&if(files&!=&null&&&&files.length&0){&
&&&&&&&&&&&&for(File&f&:&files&){&
&&&&&&&&&&&&&&&&if(getImageFile(f.getName())){&
&&&&&&&&&&&&&&&&&&&&it.add(f.getPath());&
&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&Options&bitmapFactoryOptions&=&new&BitmapFactory.Options();&
&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&bitmapFactoryOptions.inJustDecodeBounds&=&true;&
&&&&&&&&&&&&&&&&&&&&bitmapFactoryOptions.inSampleSize&=&5;&
&&&&&&&&&&&&&&&&&&&&int&outWidth&&=&bitmapFactoryOptions.outW&
&&&&&&&&&&&&&&&&&&&&int&outHeight&=&bitmapFactoryOptions.outH&
&&&&&&&&&&&&&&&&&&&&float&imagew&=&150;&
&&&&&&&&&&&&&&&&&&&&float&imageh&=&150;&
&&&&&&&&&&&&&&&&&&&&int&yRatio&=&(int)&Math.ceil(bitmapFactoryOptions.outHeight&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&/&imageh);&
&&&&&&&&&&&&&&&&&&&&int&xRatio&=&(int)&Math&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&.ceil(bitmapFactoryOptions.outWidth&/&imagew);&
&&&&&&&&&&&&&&&&&&&&if&(yRatio&&&1&||&xRatio&&&1)&{&
&&&&&&&&&&&&&&&&&&&&&&&&if&(yRatio&&&xRatio)&{&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&bitmapFactoryOptions.inSampleSize&=&yR&
&&&&&&&&&&&&&&&&&&&&&&&&}&else&{&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&bitmapFactoryOptions.inSampleSize&=&xR&
&&&&&&&&&&&&&&&&&&&&&&&&}&
&&&&&&&&&&&&&&&&&&&&}&&
&&&&&&&&&&&&&&&&&&&&bitmapFactoryOptions.inJustDecodeBounds&=&false;&
&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&bitmap&=&BitmapFactory.decodeFile(f.getPath(),&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&bitmapFactoryOptions);&
&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&srf&=&new&SoftReference&Bitmap&(bitmap);&
&&&&&&&&&&&&&&&&&&&&imageCache.put(f.getName(),&srf);&
&&&&&&&&&&&&&&&&}&
&&&&&&&&&&&&}&
&&&&&&&&}&
&&&&&&&&return&&
&&&&private&boolean&getImageFile(String&fName)&{&
&&&&&&&&boolean&&
&&&&&&&&String&end&=&fName&
&&&&&&&&&&&&&&&&.substring(fName.lastIndexOf(".")&+&1,&fName.length())&
&&&&&&&&&&&&&&&&.toLowerCase();&
&&&&&&&&if&(end.equals("jpg")&||&end.equals("gif")&||&end.equals("png")&
&&&&&&&&&&&&&&&&||&end.equals("jpeg")&||&end.equals("bmp"))&{&
&&&&&&&&&&&&re&=&true;&
&&&&&&&&}&else&{&
&&&&&&&&&&&&re&=&false;&
&&&&&&&&}&
&&&&&&&&return&&
&&&&public&class&ImageAdapter&extends&BaseAdapter{&
&&&&&&&&int&mGalleryItemB&
&&&&&&&&private&Context&mC&
&&&&&&&&private&List&String&&&
&&&&&&&&public&ImageAdapter(Context&c,&List&String&&li)&{&
&&&&&&&&&&&&mContext&=&c;&
&&&&&&&&&&&&lis&=&&
&&&&&&&&&&&&TypedArray&a&=&obtainStyledAttributes(R.styleable.Gallery);&
&&&&&&&&&&&&mGalleryItemBackground&=&a.getResourceId(R.styleable.Gallery_android_galleryItemBackground,&0);&
&&&&&&&&&&&&a.recycle();&
&&&&&&&&}&
&&&&&&&&public&int&getCount()&{&
&&&&&&&&&&&&return&lis.size();&
&&&&&&&&}&
&&&&&&&&public&Object&getItem(int&position)&{&
&&&&&&&&&&&&return&lis.get(position);&
&&&&&&&&}&
&&&&&&&&public&long&getItemId(int&position)&{&
&&&&&&&&&&&&return&&
&&&&&&&&}&
&&&&&&&&public&View&getView(int&position,&View&convertView,&ViewGroup&parent)&{&
&&&&&&&&&&&&System.out.println("lis:"+lis);&
&&&&&&&&&&&&File&file&=&new&File(it.get(position));&
&&&&&&&&&&&&SoftReference&Bitmap&&srf&=&imageCache.get(file.getName());&
&&&&&&&&&&&&Bitmap&bit&=&srf.get();&
&&&&&&&&&&&&ImageView&i&=&new&ImageView(mContext);&
&&&&&&&&&&&&i.setImageBitmap(bit);&
&&&&&&&&&&&&i.setScaleType(ImageView.ScaleType.FIT_XY);&
&&&&&&&&&&&&i.setLayoutParams(&new&Gallery.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT,&
&&&&&&&&&&&&&&&&&&&&WindowManager.LayoutParams.WRAP_CONTENT));&
&&&&&&&&&&&&return&i;&
&&&&&&&&}&
& & 上面两种方式第一种直接使用边界压缩,第二种在使用边界压缩的情况下间接的使用了软引用来避免OOM,但大家都知道,这些函数在完成decode后,最终都是通过java层的createBitmap来完成的,需要消耗更多内存,如果图片多且大,这种方式还是会引用OOM异常的,不着急,有的是办法解决,继续看,以下方式也大有妙用的:
1.&InputStream&is&=&this.getResources().openRawResource(R.drawable.pic1);&
&&&&&BitmapFactory.Options&options=new&BitmapFactory.Options();&
&&&&&options.inJustDecodeBounds&=&false;&
&&&&&options.inSampleSize&=&10;&&&//width,hight设为原来的十分一&
&&&&&Bitmap&btp&=BitmapFactory.decodeStream(is,null,options);&
2.&if(!bmp.isRecycle()&){&
&&&&&&&&&bmp.recycle()&&&//回收图片所占的内存&
&&&&&&&&&system.gc()&&//提醒系统及时回收&
上面代码与下面代码大家可分开使用,也可有效缓解内存问题哦...吼吼...
/**&这个地方大家别搞混了,为了方便小马把两个贴一起了,使用的时候记得分开使用
&&&&&*&以最省内存的方式读取本地资源的图片&
&&&&&*/&&&
&&&&public&static&Bitmap&readBitMap(Context&context,&int&resId){&&&
&&&&&&&&BitmapFactory.Options&opt&=&new&BitmapFactory.Options();&&&
&&&&&&&&opt.inPreferredConfig&=&Bitmap.Config.RGB_565;&&&&
&&&&&&&opt.inPurgeable&=&true;&&&
&&&&&&&opt.inInputShareable&=&true;&&&
&&&&&&&&&&//获取资源图片&&&
&&&&&&&InputStream&is&=&context.getResources().openRawResource(resId);&&&
&&&&&&&&&&&return&BitmapFactory.decodeStream(is,null,opt);&&&
& &3:大家可以选择在合适的地方使用以下代码动态并自行显式调用GC来回收内存:
if(bitmapObject.isRecycled()==false)&&
&&&&&&&&&bitmapObject.recycle();&&&&
& &4:这个就好玩了,优化Dalvik虚拟机的堆内存分配,听着很强大,来看下具体是怎么一回事
& & &对于Android平台来说,其托管层使用的Dalvik JavaVM从目前的表现来看还有很多地方可以优化处理,比如我们在开发一些大型游戏或耗资源的应用中可能考虑手动干涉GC处理,使用 dalvik.system.VMRuntime类提供的setTargetHeapUtilization方法可以增强程序堆内存的处理效率。当然具体原理我们可以参考开源工程,这里我们仅说下使用方法:&代码如下:
private&final&static&floatTARGET_HEAP_UTILIZATION&=&0.75f;&&
在程序onCreate时就可以调用&
VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION);&
& &5:自定义我们的应用需要多大的内存,这个好暴力哇,强行设置最小内存大小,代码如下:
private&final&static&int&CWJ_HEAP_SIZE&=&6*&&;&
&//设置最小heap内存为6MB大小&
VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE);&
& &&好了,文章写完了,片幅有点长,因为涉及到的东西太多了,其它文章小马都会贴源码,这篇文章小马是直接在项目中用三款安卓真机测试的,有效果,项目原码就不在这贴了,不然泄密了都,吼吼,但这里讲下还是会因为手机的不同而不同,大家得根据自己需求选择合适的方式来避免OOM,大家加油呀,每天都有或多或少的收获,这也算是进步,加油加油!
本文出自 && 博客,请务必保留此出处
阅读(...) 评论() &}

我要回帖

更多关于 android 加载gif图片 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信