android內(nèi)存優(yōu)化之圖片優(yōu)化
對圖片本身進行操作。盡量不要使用setImageBitmap、setImageResource、BitmapFactory.decodeResource來設(shè)置一張大圖,因為這些方法在完成decode后,最終都是通過java層的createBitmap來完成的,需要消耗更多內(nèi)存。因此,改用先通過BitmapFactory.decodeStream方法,創(chuàng)建出一個bitmap,再將其設(shè)為ImageView的source,decodeStream最大的秘密在于其直接調(diào)用JNI>>nativeDecodeAsset()來完成decode,無需再使用java層的createBitmap,從而節(jié)省了java層的空間。如果在讀取時加上圖片的Config參數(shù),可以更有效的減少加載的內(nèi)存,從而更有效阻止拋出內(nèi)存異常。另外,decodeStream直接拿圖片來讀取字節(jié)碼了,不會根據(jù)機器的各種分辨率來自動適應(yīng),使用了decodeStream之后,需要在hdpi和mdpi,ldpi中配置相應(yīng)的圖片資源,否則在不同分辨率機器上都是同樣大?。ㄏ袼攸c數(shù)量),顯示出來的大小就不對了。
InputStreamis=this.getResources().openRawResource(R.drawable.pic1);
BitmapFactory.Optionsoptions=newBitmapFactory.Options();
options.inJustDecodeBounds=false;
options.inSampleSize=10;//width,hight設(shè)為原來的十分一
Bitmapbtp=BitmapFactory.decodeStream(is,null,options);
if(!bmp.isRecycle()){
bmp.recycle()//回收圖片所占的內(nèi)存
system.gc()//提醒系統(tǒng)及時回收
}
/**
*以最省內(nèi)存的方式讀取本地資源的圖片
*@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的指數(shù)值,值越大會導(dǎo)致圖片不清晰。長度、寬度都只有原圖片的1/2。圖片大小減少,占用的內(nèi)存自然也變小了。這么做的弊端是圖片質(zhì)量變差,inSampleSize的值越大,圖片的質(zhì)量就越差。由于各手機廠商縮放圖片的算法不同,在不同手機上的縮放圖片質(zhì)量可能會不同。筆者就遭遇過moto手機上圖片縮放后質(zhì)量可以接受,三星手機上同樣的縮放比例,質(zhì)量卻差很多的情況。
Android中有四種,分別是:
ALPHA_8:每個像素占用1byte內(nèi)存
ARGB_4444:每個像素占用2byte內(nèi)存
ARGB_8888:每個像素占用4byte內(nèi)存
RGB_565:每個像素占用2byte內(nèi)存
Android默認(rèn)的顏色模式為ARGB_8888,這個顏色模式色彩最細(xì)膩,顯示質(zhì)量最高。但同樣的,占用的內(nèi)存也最大。
以上代碼即是將1.png以ARGB_4444模式讀出。內(nèi)存減少雖然不如第一種方法明顯,但是對于大多數(shù)圖片,看不出與ARGB_8888模式有什么差別。不過在讀取有漸變效果的圖片時,可能有顏色條出現(xiàn)。另外,會影響圖片的特效處理。
優(yōu)化Dalvik虛擬機的堆內(nèi)存分配。對于Android平臺來說,其托管層使用的DalvikJavaVM從目前的表現(xiàn)來看還有很多地方可以優(yōu)化處理,比如我們在開發(fā)一些大型游戲或耗資源的應(yīng)用中可能考慮手動干涉GC處理,使用dalvik.system.VMRuntime類提供的setTargetHeapUtilization方法可以增強程序堆內(nèi)存的處理效率。使用方法:
privatefinalstaticfloatTARGET_HEAP_UTILIZATION=0.75f;
VMRuntime.getRuntime().setTargetHeapUtilization(TARGET_HEAP_UTILIZATION);
即可。
還有就是可以定義堆內(nèi)存的大小。
privatefinalstaticintCWJ_HEAP_SIZE=6*1024*1024;VMRuntime.getRuntime().setMinimumHeapSize(CWJ_HEAP_SIZE);//設(shè)置最小heap內(nèi)存為6MB大小
調(diào)用圖片的recycle()方法:
這個其實不是真正降低圖片內(nèi)存的方法。主要目的是標(biāo)記圖片對象,方便回收圖片對象的本地數(shù)據(jù)。圖片對象的本地數(shù)據(jù)占用的內(nèi)存最大,而且與程序Java部分的內(nèi)存是分開計算的。所以經(jīng)常出現(xiàn)Javaheap足夠使用,而圖片發(fā)生OutOfMemoryError的情況。在圖片不使用時調(diào)用該方法,可以有效降低圖片本地數(shù)據(jù)的峰值,從而減少OutOfMemoryError的概率。不過調(diào)用了recycle()的圖片對象處于“廢棄”狀態(tài),調(diào)用時會造成程序錯誤。所以在無法保證該圖片對象絕對不會被再次調(diào)用的情況下,不建議使用該方法。特別要注意已經(jīng)用setImageBitmap(Bitmapimg)方法分配給控件的圖片對象,可能會被系統(tǒng)類庫調(diào)用,造成程序錯誤。
使用Matrix對象放大的圖片如何更改顏色模式:
雖然使用Matrix對象放大圖片,必定會耗費更多的內(nèi)存,但有時候也不得不這樣做。放大后的圖片使用的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。但是系統(tǒng)會自動回收img1,所以實際內(nèi)存還是減少了。
相關(guān)文章
Android開發(fā)實現(xiàn)長按返回鍵彈出關(guān)機框功能
這篇文章主要介紹了Android開發(fā)實現(xiàn)長按返回鍵彈出關(guān)機框功能,涉及Android針對長按事件的響應(yīng)與處理相關(guān)操作技巧,需要的朋友可以參考下2017-09-09Android獲取WebView加載url的請求錯誤碼 【推薦】
這篇文章主要介紹了Android獲取WebView加載url的請求錯誤碼 ,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2019-06-06Android APK使用Debug簽名重新打包 Eclipse更改默認(rèn)Debug簽名
這篇文章主要介紹了Android APK使用Debug簽名重新打包 Eclipse更改默認(rèn)Debug簽名等內(nèi)容,需要的朋友可以參考下2015-04-04ListView實現(xiàn)聊天列表之處理不同數(shù)據(jù)項
這篇文章主要為大家詳細(xì)介紹了ListView實現(xiàn)聊天列表之處理不同數(shù)據(jù)項,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-11-11Android仿淘寶頭條向上滾動廣告條ViewFlipper
這篇文章主要為大家詳細(xì)介紹了Android仿淘寶頭條向上滾動廣告條ViewFlipper,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05Android使用Intent傳遞組件大數(shù)據(jù)
這篇文章主要介紹了Android使用Intent傳遞組件大數(shù)據(jù),文章圍繞主題展開詳細(xì)的內(nèi)容詳情,感興趣的朋友可以參考一下2022-07-07