国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Bitmap避免OOM

EastWoodYang / 705人閱讀

摘要:我知道最近世麟心情是錯(cuò)綜復(fù)雜,但還好的是絕大多數(shù)程序員都是特別有善心的。如果圖像數(shù)據(jù)較大就會(huì)造成對(duì)象申請(qǐng)的內(nèi)存較多,如果圖像過多就會(huì)造成內(nèi)存不夠用自然就會(huì)出現(xiàn)的現(xiàn)象。第二次將設(shè)置為再次調(diào)用函數(shù)時(shí)就能生成了。

目錄介紹

01.先看一個(gè)需求分析案例

02.Bitmap占用內(nèi)存介紹

03.影響B(tài)itmap占用內(nèi)存因素

04.圖像加載的方式

05.加載圖像內(nèi)存去哪里了

06.具體實(shí)現(xiàn)加載圖片步驟

希望世麟兄弟母親盡快好起來

和南塵(世麟)認(rèn)識(shí)與網(wǎng)絡(luò),估計(jì)好多程序員都看過他的文章,我也是。雖然沒有見過面,但是微信聊過多次,感覺人非常不錯(cuò)。都具有共同的愛好,喜歡寫技術(shù)博客和開源項(xiàng)目,算得上同道中人。

對(duì)于這次他遇到的事情,我的確很佩服他那種承擔(dān)的責(zé)任和勇氣。對(duì)于任何一個(gè)出身一般的人來說,大多數(shù)家庭都是難以承擔(dān)疾病所帶來的費(fèi)用,即使有勇氣承擔(dān),那經(jīng)濟(jì)上也的確讓人壓力很大,如果可以盡綿薄之力,那就特別感謝大家呢!

雖然大多數(shù)技術(shù)平臺(tái)發(fā)這個(gè)水滴籌,有些人會(huì)表示不理解,有的甚至說會(huì)影響社區(qū)氛圍。我覺得這種擔(dān)心很正常,但是有點(diǎn)把問題放大了,首先這個(gè)是一個(gè)特別小概率的事件,并不會(huì)存在說大家都這樣做就造成不好的影響。其次有人還說,會(huì)過渡消費(fèi)社會(huì)這種同情和愛心,這種擔(dān)心挺好,但是人總是會(huì)有分辨是非的能力,如果能夠幫忙那就盡綿薄之力,如果不能幫忙那也不要亂扣帽子。

我知道最近世麟心情是錯(cuò)綜復(fù)雜,但還好的是絕大多數(shù)程序員都是特別有善心的。我始終覺得一個(gè)能夠堅(jiān)持寫技術(shù)博客,而且還寫了這么多,掘金還是以前的掘金,沒有發(fā)生變化。

程序員爸爸癱瘓14年,媽媽又這樣,幫幫南塵!

01.先看一個(gè)需求分析案例

案例說明

加載一個(gè)本地的大圖片或者網(wǎng)絡(luò)圖片,從加載到設(shè)置到View上,如何減下內(nèi)存,避免加載圖片OOM。

案例分析

在展示高分辨率圖片的時(shí)候,最好先將圖片進(jìn)行壓縮。壓縮后的圖片大小應(yīng)該和用來展示它的控件大小相近,在一個(gè)很小的ImageView上顯示一張超大的圖片不會(huì)帶來任何視覺上的好處,但卻會(huì)占用相當(dāng)多寶貴的內(nèi)存,而且在性能上還可能會(huì)帶來負(fù)面影響。

02.Bitmap占用內(nèi)存介紹

網(wǎng)絡(luò)圖片計(jì)算Bitmap的內(nèi)存大小

bitmap內(nèi)存大小 = 圖片長(zhǎng)度 x 圖片寬度 x 單位像素占用的字節(jié)數(shù)

起決定因素就是最后那個(gè)參數(shù)了,Bitmap"常見有2種編碼方式:ARGB_8888和RGB_565,ARGB_8888每個(gè)像素點(diǎn)4個(gè)byte,RGB_565是2個(gè)byte,一般都采用ARGB_8888這種。那么常見的1080*1920的圖片內(nèi)存占用就是:1920 x 1080 x 4 = 7.9M

加載本地資源計(jì)算Bitmap的內(nèi)存大小

加載一張本地資源圖片,那么它占用的內(nèi)存 = width height nTargetDensity/inDensity 一個(gè)像素所占的內(nèi)存。

詳細(xì)可以看這篇文章04.Bitmap計(jì)算內(nèi)存

正確說法,這個(gè)注意呢?計(jì)算公式如下所示

對(duì)資源文件:width height nTargetDensity/inDensity nTargetDensity/inDensity 一個(gè)像素所占的內(nèi)存;

別的:width height 一個(gè)像素所占的內(nèi)存;

03.影響B(tài)itmap占用內(nèi)存因素

影響B(tài)itmap占用內(nèi)存的因素:

圖片最終加載的分辨率;

圖片的格式(PNG/JPEG/BMP/WebP);

圖片所存放的drawable目錄;

圖片屬性設(shè)置的色彩模式;

設(shè)備的屏幕密度;

04.圖像加載的方式

獲取圖像的來源一般有三種源頭:

1.從網(wǎng)絡(luò)加載2.從文件讀取3.從資源文件加載

針對(duì)這三種情況我們一般使用BitmapFactory的

decodeStream,decodeFile,decodeResource,這三個(gè)函數(shù)來獲取到bitmap然后再調(diào)用ImageView的setImageBitmap函數(shù)進(jìn)行展現(xiàn)。

05.加載圖像內(nèi)存去哪里了

思考一下:內(nèi)存去哪里了(為什么被消耗了這么多)?

其實(shí)我們的內(nèi)存就是去bitmap里了,BitmapFactory的每個(gè)decode函數(shù)都會(huì)生成一個(gè)bitmap對(duì)象,用于存放解碼后的圖像,然后返回該引用。如果圖像數(shù)據(jù)較大就會(huì)造成bitmap對(duì)象申請(qǐng)的內(nèi)存較多,如果圖像過多就會(huì)造成內(nèi)存不夠用自然就會(huì)出現(xiàn)out of memory的現(xiàn)象。

為何容易OOM?

通過BitmapFactory的decode的這些方法會(huì)嘗試為已經(jīng)構(gòu)建的bitmap分配內(nèi)存,這時(shí)就會(huì)很容易導(dǎo)致OOM出現(xiàn)。為此每一種解析方法都提供了一個(gè)可選的BitmapFactory.Options參數(shù),將這個(gè)參數(shù)的inJustDecodeBounds屬性設(shè)置為true就可以讓解析方法禁止為bitmap分配內(nèi)存,返回值也不再是一個(gè)Bitmap對(duì)象,而是null。

06.具體實(shí)現(xiàn)加載圖片步驟

為了避免OOM異常,最好在解析每張圖片的時(shí)候都先檢查一下圖片的大小,除非你非常信任圖片的來源,保證這些圖片都不會(huì)超出你程序的可用內(nèi)存。

現(xiàn)在圖片的大小已經(jīng)知道了,我們就可以決定是把整張圖片加載到內(nèi)存中還是加載一個(gè)壓縮版的圖片到內(nèi)存中。以下幾個(gè)因素是我們需要考慮的:

預(yù)估一下加載整張圖片所需占用的內(nèi)存。

為了加載這一張圖片你所愿意提供多少內(nèi)存。

用于展示這張圖片的控件的實(shí)際大小。

當(dāng)前設(shè)備的屏幕尺寸和分辨率。

比如,你的ImageView只有128x96像素的大小,只是為了顯示一張縮略圖,這時(shí)候把一張2048x1536像素的圖片完全加載到內(nèi)存中顯然是不值得的。

6.1 對(duì)圖片進(jìn)行壓縮

怎樣才能對(duì)圖片進(jìn)行壓縮呢?

通過設(shè)置BitmapFactory.Options中inSampleSize的值就可以實(shí)現(xiàn)。

比如我們有一張2048x1536像素的圖片,將inSampleSize的值設(shè)置為4,就可以把這張圖片壓縮成512x384像素。

原本加載這張圖片需要占用13M的內(nèi)存,壓縮后就只需要占用0.75M了(假設(shè)圖片是ARGB_8888類型,即每個(gè)像素點(diǎn)占用4個(gè)字節(jié))。

下面的方法可以根據(jù)傳入的寬和高,計(jì)算出合適的inSampleSize值:

public static 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) { 
        // 計(jì)算出實(shí)際寬高和目標(biāo)寬高的比率 
        final int heightRatio = Math.round((float) height / (float) reqHeight); 
        final int widthRatio = Math.round((float) width / (float) reqWidth); 
        // 選擇寬和高中最小的比率作為inSampleSize的值,這樣可以保證最終圖片的寬和高 
        // 一定都會(huì)大于等于目標(biāo)的寬和高。 
        inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; 
    } 
    return inSampleSize; 
}  

6.2 設(shè)置BitmapFactory.Options屬性

大概步驟如下所示

要將BitmapFactory.Options的inJustDecodeBounds屬性設(shè)置為true,解析一次圖片。注意這個(gè)地方是核心,這個(gè)解析圖片并沒有生成bitmap對(duì)象(也就是說沒有為它分配內(nèi)存控件),而僅僅是拿到它的寬高等屬性。

然后將BitmapFactory.Options連同期望的寬度和高度一起傳遞到到calculateInSampleSize方法中,就可以得到合適的inSampleSize值了。這一步會(huì)壓縮圖片。

之后再解析一次圖片,使用新獲取到的inSampleSize值,并把inJustDecodeBounds設(shè)置為false,就可以得到壓縮后的圖片了。此時(shí)才正式創(chuàng)建了bitmap對(duì)象,由于前面已經(jīng)對(duì)它壓縮了,所以你會(huì)發(fā)現(xiàn)此時(shí)所占內(nèi)存大小已經(jīng)很少了。

具體的實(shí)現(xiàn)代碼

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, 
        int reqWidth, int reqHeight) { 
    // 第一次解析將inJustDecodeBounds設(shè)置為true,來獲取圖片大小 
    final BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeResource(res, resId, options); 
    // 調(diào)用上面定義的方法計(jì)算inSampleSize值 
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); 
    // 使用獲取到的inSampleSize值再次解析圖片 
    options.inJustDecodeBounds = false; 
    return BitmapFactory.decodeResource(res, resId, options); 
}

思考:inJustDecodeBounds這個(gè)參數(shù)是干什么的?

如果設(shè)置為true則表示decode函數(shù)不會(huì)生成bitmap對(duì)象,僅是將圖像相關(guān)的參數(shù)填充到option對(duì)象里,這樣我們就可以在不生成bitmap而獲取到圖像的相關(guān)參數(shù)了。

為何設(shè)置兩次inJustDecodeBounds屬性?

第一次:設(shè)置為true則表示decode函數(shù)不會(huì)生成bitmap對(duì)象,僅是將圖像相關(guān)的參數(shù)填充到option對(duì)象里,這樣我們就可以在不生成bitmap而獲取到圖像的相關(guān)參數(shù)。

第二次:將inJustDecodeBounds設(shè)置為false再次調(diào)用decode函數(shù)時(shí)就能生成bitmap了。而此時(shí)的bitmap已經(jīng)壓縮減小很多了,所以加載到內(nèi)存中并不會(huì)導(dǎo)致OOM。

6.3 設(shè)置bitmap到View上

將任意一張圖片壓縮成100*100的縮略圖,并在ImageView上展示。

mImageView.setImageBitmap( 
    decodeSampledBitmapFromResource(getResources(), R.id.ycimage, 100, 100)); 

其他介紹 01.關(guān)于博客匯總鏈接

1.技術(shù)博客匯總

2.開源項(xiàng)目匯總

3.生活博客匯總

4.喜馬拉雅音頻匯總

5.其他匯總

02.關(guān)于我的博客

github:https://github.com/yangchong211

知乎:https://www.zhihu.com/people/...

簡(jiǎn)書:http://www.jianshu.com/u/b7b2...

csdn:http://my.csdn.net/m0_37700275

喜馬拉雅聽書:http://www.ximalaya.com/zhubo...

開源中國(guó):https://my.oschina.net/zbj161...

泡在網(wǎng)上的日子:http://www.jcodecraeer.com/me...

郵箱:yangchong211@163.com

阿里云博客:https://yq.aliyun.com/users/a... 239.headeruserinfo.3.dT4bcV

segmentfault頭條:https://segmentfault.com/u/xi...

掘金:https://juejin.im/user/593943...

項(xiàng)目案例:https://github.com/yangchong2...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/75334.html

相關(guān)文章

  • Android性能優(yōu)化之內(nèi)存優(yōu)化

    摘要:導(dǎo)語智能手機(jī)發(fā)展到今天已經(jīng)有十幾個(gè)年頭,手機(jī)的軟硬件都已經(jīng)發(fā)生了翻天覆地的變化,特別是陣營(yíng),從一開始的一兩百到今天動(dòng)輒,內(nèi)存。恰好最近做了內(nèi)存優(yōu)化相關(guān)的工作,這里也對(duì)內(nèi)存優(yōu)化相關(guān)的知識(shí)做下總結(jié)。 導(dǎo)語 智能手機(jī)發(fā)展到今天已經(jīng)有十幾個(gè)年頭,手機(jī)的軟硬件都已經(jīng)發(fā)生了翻天覆地的變化,特別是Android陣營(yíng),從一開始的一兩百M(fèi)到今天動(dòng)輒4G,6G內(nèi)存。然而大部分的開發(fā)者觀看下自己的異常上報(bào)系...

    cheng10 評(píng)論0 收藏0
  • LeakCanary傻瓜式的內(nèi)存泄露檢測(cè)工具

    摘要:另一種方式就是是一個(gè)簡(jiǎn)單的,方便的內(nèi)存檢測(cè)工具,可以輕易的發(fā)現(xiàn)內(nèi)存問題,還會(huì)生成更加簡(jiǎn)單清晰的報(bào)告。是一個(gè)開源的檢測(cè)內(nèi)存泄露的庫(kù)。 在開發(fā)Android應(yīng)用的過程中如果需要處理圖片或者大量數(shù)據(jù)的時(shí)候,就有可能會(huì)遇到OOM(java.lang.OutOfMemoryError),一般出現(xiàn)最多的是在創(chuàng)建Bitmap上,也有可能是在內(nèi)存中處理了大量的數(shù)據(jù)上。出現(xiàn)OOM應(yīng)用會(huì)直接崩潰,即使沒有...

    shixinzhang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<