android內存優化之圖片優化

對圖片自己進行操做。儘可能不要使用setImageBitmap、setImageResource、BitmapFactory.decodeResource來設置一張大圖,由於這些方法在完成decode後,最終都是經過java層的createBitmap來完成的,須要消耗更多內存

對圖片自己進行操做。儘可能不要使用setImageBitmap、setImageResource、BitmapFactory.decodeResource來設置一張大圖,由於這些方法在完成decode後,最終都是經過java層的createBitmap來完成的,須要消耗更多內存。所以,改用先經過BitmapFactory.decodeStream方法,建立出一個bitmap,再將其設爲ImageView的source,decodeStream最大的祕密在於其直接調用JNI>>nativeDecodeAsset()來完成decode,無需再使用java層的createBitmap,從而節省了java層的空間。若是在讀取時加上圖片的Config參數,能夠更有效的減小加載的內存,從而更有效阻止拋出內存異常。另外,decodeStream直接拿圖片來讀取字節碼了,不會根據機器的各類分辨率來自動適應,使用了decodeStream以後,須要在hdpi和mdpi,ldpi中配置相應的圖片資源,不然在不一樣分辨率機器上都是一樣大小(像素點數量),顯示出來的大小就不對了。  java

複製代碼代碼以下:

InputStreamis=this.getResources().openRawResource(R.drawable.pic1); 
BitmapFactory.Optionsoptions=newBitmapFactory.Options(); 
options.inJustDecodeBounds=false; 
options.inSampleSize=10;//width,hight設爲原來的十分一 
Bitmapbtp=BitmapFactory.decodeStream(is,null,options); 

複製代碼代碼以下:

if(!bmp.isRecycle()){ 
bmp.recycle()//回收圖片所佔的內存 
system.gc()//提醒系統及時回收 


複製代碼代碼以下:

/** 
*以最省內存的方式讀取本地資源的圖片 
*@paramcontext 
*@paramresId 
*@return 
*/ 
publicstaticBitmapreadBitMap(Contextcontext,intresId){ 
BitmapFactory.Optionsopt=newBitmapFactory.Options(); 
opt.inPreferredConfig=Bitmap.Config.RGB_565; 
opt.inPurgeable=true; 
opt.inInputShareable=true; 
//獲取資源圖片 
InputStreamis=context.getResources().openRawResource(resId); 
returnBitmapFactory.decodeStream(is,null,opt); 


option中的值指的是,圖片進行縮放的比例,SDK中建議其值是2的指數值,值越大會致使圖片不清晰。長度、寬度都只有原圖片的1/2。圖片大小減小,佔用的內存天然也變小了。這麼作的弊端是圖片質量變差,inSampleSize的值越大,圖片的質量就越差。因爲各手機廠商縮放圖片的算法不一樣,在不一樣手機上的縮放圖片質量可能會不一樣。筆者就遭遇過moto手機上圖片縮放後質量能夠接受,三星手機上一樣的縮放比例,質量卻差不少的狀況。 

Android中有四種,分別是: 
ALPHA_8:每一個像素佔用1byte內存 
ARGB_4444:每一個像素佔用2byte內存 
ARGB_8888:每一個像素佔用4byte內存 
RGB_565:每一個像素佔用2byte內存 
Android默認的顏色模式爲ARGB_8888,這個顏色模式色彩最細膩,顯示質量最高。但一樣的,佔用的內存也最大。 
以上代碼便是將1.png以ARGB_4444模式讀出。內存減小雖然不如第一種方法明顯,可是對於大多數圖片,看不出與ARGB_8888模式有什麼差異。不過在讀取有漸變效果的圖片時,可能有顏色條出現。另外,會影響圖片的特效處理。 
優化Dalvik虛擬機的堆內存分配。對於Android平臺來講,其託管層使用的DalvikJavaVM從目前的表現來看還有不少地方能夠優化處理,好比咱們在開發一些大型遊戲或耗資源的應用中可能考慮手動干涉GC處理,使用dalvik.system.VMRuntime類提供的setTargetHeapUtilization方法能夠加強程序堆內存的處理效率。使用方法: 
複製代碼代碼以下:

privatefinalstaticfloatTARGET_HEAP_UTILIZATION=0.75f; 
VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION); 

便可。 
還有就是能夠定義堆內存的大小。 
複製代碼代碼以下:

privatefinalstaticintCWJ_HEAP_SIZE=6*1024*1024;VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE);//設置最小heap內存爲6MB大小 

調用圖片的recycle()方法: 
這個其實不是真正下降圖片內存的方法。主要目的是標記圖片對象,方便回收圖片對象的本地數據。圖片對象的本地數據佔用的內存最大,並且與程序Java部分的內存是分開計算的。因此常常出現Javaheap足夠使用,而圖片發生OutOfMemoryError的狀況。在圖片不使用時調用該方法,能夠有效下降圖片本地數據的峯值,從而減小OutOfMemoryError的機率。不過調用了recycle()的圖片對象處於「廢棄」狀態,調用時會形成程序錯誤。因此在沒法保證該圖片對象絕對不會被再次調用的狀況下,不建議使用該方法。特別要注意已經用setImageBitmap(Bitmapimg)方法分配給控件的圖片對象,可能會被系統類庫調用,形成程序錯誤。 

使用Matrix對象放大的圖片如何更改顏色模式: 
雖然使用Matrix對象放大圖片,一定會耗費更多的內存,但有時候也不得不這樣作。放大後的圖片使用的ARGB_8888顏色模式,就算原圖片是ARGB_4444顏色模式也同樣,並且沒有辦法在放大時直接指定顏色模式。能夠採用如下辦法更改圖片顏色模式。 
代碼以下 
複製代碼代碼以下:
Matrixmatrix=newMatrix();  floatnewWidth=200;//圖片放大後的寬度  floatnewHeight=300;//圖片放大後的長度  matrix.postScale(newWidth/img.getWidth(),newHeight/img.getHeight());  Bitmapimg1=Bitmap.createBitmap(img,0,0,img.getWidth(),img.getHeight(),matrix,true);//獲得放大的圖片  img2=img1.copy(Bitmap.Config.ARGB_4444,false);//獲得ARGB_4444顏色模式的圖片  img=null;  img1=null; 
這裏比起原來的圖片額外生成了一個圖片對象img1。可是系統會自動回收img1,因此實際內存仍是減小了。
相關文章
相關標籤/搜索