Android性能優(yōu)化:Bitmap詳解&你的Bitmap占多大內(nèi)存铺遂?

在開(kāi)發(fā)app時(shí),顯示一張本地圖片剪廉,這張圖片在加載時(shí)會(huì)占用大多內(nèi)存呢?猜測(cè)占用內(nèi)存大小和以下幾個(gè)因素有關(guān):

  1. 設(shè)計(jì)師切圖炕檩,圖片本身的分辨率斗蒋;
  2. 圖片所放文件夾代表的 密度 dpi;
  3. 手機(jī)自身的屏幕密度笛质;
  4. 經(jīng)過(guò)系統(tǒng)縮放得到的最終加載到手機(jī)上圖片的密度和占用的內(nèi)存泉沾。

我們知道Android中在加載本地大圖時(shí),很容易OOM妇押,主要原因在于加載的Bitmap占用內(nèi)存太大跷究。接下來(lái)將圍繞以下幾個(gè)問(wèn)題說(shuō)明如何計(jì)算一張Bitmap占用的內(nèi)存大小。

  1. 將一張分辨率為 720x1080 的圖片放到 xxhdpi 或者 hdpi 敲霍,同放在 xhdpi 標(biāo)準(zhǔn)文件夾下俊马,對(duì)于同一臺(tái)手機(jī)占用內(nèi)存大小是否有變化丁存?
  2. 同一張分辨率為 720x1080 的圖片被不同屏幕分辨率的手機(jī)加載,BitmapFactory 的成員變量 inDensity柴我、 inScreenDensity解寝、 inTargetDensity 會(huì)怎樣變化?這些值又是怎樣被賦值的艘儒,又是怎樣進(jìn)行縮放的聋伦?
  3. 使用 decodeResource() 和 decodeStream() 有什么區(qū)別?
  4. Options 的 inDensity界睁、 inTargetDensity 和 輸出的 Bitmap 的 mDensity 有什么關(guān)系觉增?Bitmap 的 mWidth、 mHeight 與 Options 的 outputWidth翻斟、 outputHeight 有什么關(guān)系逾礁?
  5. 這些同計(jì)算 Bitmap 內(nèi)存占用大小的 長(zhǎng)寬有什么關(guān)系?

在回答這些問(wèn)題之前杨赤,先介紹一下DisplayMetrics和Bitmap及其相關(guān)類(lèi)敞斋。

一、DisplayMetrics和Bitmap及其相關(guān)類(lèi)

DisplayMetrics

說(shuō)明:屏幕密度相關(guān)類(lèi)疾牲,可以用于獲取屏幕高和寬以及屏幕密度density植捎、每英寸點(diǎn)數(shù)densityDpi . 這里,density 數(shù)值為 1dp = density px阳柔;在 DisplayMetrics 中焰枢,這兩個(gè)是線性相關(guān):


屏幕密度對(duì)照表.png
Bitmap

說(shuō)明:Bitmap 在 Android 中指的是一張圖片,可以是 png舌剂,也可以是 jpg等其他圖片格式济锄。
作用:可以獲取圖像文件信息,對(duì)圖像進(jìn)行剪切霍转、旋轉(zhuǎn)荐绝、縮放、壓縮等操作避消,并可以指定格式保存圖像文件低滩。

Bitmap.Config

說(shuō)明:Bitmap 格式。除了尺寸外岩喷,影響一個(gè)圖片占用空間還有色彩細(xì)節(jié)恕沫。位圖位數(shù)越高表示可以存儲(chǔ)的顏色信息越多,圖像也就越清晰逼真纱意。

  • ALPHA_8:表示8位Alpha位圖婶溯,每像素占1byte內(nèi)存;
  • RGB_565:表示R為5位,G為6位迄委,B為5位褐筛,一共16位,每像素占2byte內(nèi)存跑筝;
  • ARGB_4444:表示16位位圖死讹,每像素占2byte內(nèi)存(poor quality - Android Deprecated);
  • ARGB_8888:表示32位ARGB位圖曲梗,每像素占4byte內(nèi)存(Recommended)赞警。
BitmapFactory

說(shuō)明:提供解析Bitmap的靜態(tài)工廠方法。

BitmapFactory.Options

說(shuō)明:用于解碼Bitmap時(shí)的各種參數(shù)控制虏两。
幾個(gè)重要參數(shù):

inBitmap:在解析Bitmap時(shí)重用該Bitmap愧旦,但是必須相同大小的Bitmap & inMutable = true 才可重用;
inMutable :配置Bitmap是否可更改定罢,如每隔幾個(gè)像素給Bmp添加一條直線笤虫;
inPreferredConfig:Config顏色位數(shù),默認(rèn)值為Bitmap.Config.ARGB_888祖凫;
inDither:是否抖動(dòng)琼蚯,默認(rèn)false(Android Depracated);
inPremultiplied:默認(rèn)true引矩,一般不改變其值荞驴。
inPurgeable:當(dāng)存儲(chǔ)像素內(nèi)存空間 在系統(tǒng)內(nèi)存不足時(shí) 是否可被回收(Android L Deprecated);
inInputShareable:是否可以共享一個(gè) InputStream (Android L Deprecated);
inPreferQualityOverSpeed:為true時(shí)會(huì)優(yōu)先保證 Bitmap 質(zhì)量,其次是解碼速度(Android N Deprecated);
inTempStorage:解碼時(shí)的臨時(shí)空間蓖乘,建議 16K稠屠;
inJustDecodeBounds:為true時(shí)僅返回 Bitmap 寬高等屬性峦睡,返回bmp=null,為false時(shí)才返回占內(nèi)存的 bmp权埠;
inSampleSize:表示 Bitmap 的壓縮比例榨了,值必須 > 1 & 是2的冪次方。inSampleSize = 2 時(shí)攘蔽,表示壓縮寬高各1/2龙屉,最后返回原始圖1/4大小的Bitmap;
inDensity:表示 Bitmap 像素密度满俗;
inTargetDensity:表示 Bitmap 最終的像素密度转捕;
inScreenDensity:表示當(dāng)前屏幕的像素密度;
inScaled:默認(rèn)為true漫雷,是否支持縮放瓜富,設(shè)置為true時(shí)鳍咱,Bitmap將以 inTargetDensity 的值進(jìn)行縮放降盹;
outputWidth:返回的 Bitmap的寬;
outputHeight:返回的 Bitmap的高。

以一張類(lèi)圖說(shuō)明Bitmap蓄坏、BitmapFactory和BitmapFactory.Options三者之間的關(guān)系价捧,如下圖所示:


Bitmap、BitmapFactory涡戳、Options關(guān)系類(lèi)圖.png

二结蟋、ImageView 設(shè)置圖片 & Bitmap創(chuàng)建流程

ImageView 設(shè)置圖片

一般地,給 ImageView 設(shè)置資源圖片時(shí)渔彰,會(huì)用到四種方式:setImageResource(), setImageUri(), setImageBitmap(), setImageDrawable嵌屎。這四種方式有什么區(qū)別呢?用一張圖來(lái)展示:

ImageView設(shè)置圖片四種方法流程.png

總結(jié):由上可知恍涂,ImageView設(shè)置本地圖片會(huì)先生成 Bitmap 再將 Bitmap 轉(zhuǎn)成 Drawable宝惰,最終通過(guò) setImageDrawable() 設(shè)置;
【所以這步是否可以看做使用 setImageDrawable 會(huì)跳過(guò)讀取和解碼 Bitmap 操作再沧,為最優(yōu)設(shè)置本地圖片方式呢尼夺?
—— 需測(cè)試內(nèi)存占用情況方可驗(yàn)證〕慈常】

Bitmap創(chuàng)建流程

BitmapFactory 提供了五種方式來(lái)創(chuàng)建Bitmap淤堵,分別是:decodeFile, decodeResource, decodeByteArray, decodeStream, decodeFileDescription,這里只介紹常見(jiàn)三種方式創(chuàng)建流程如下:

Bitmap創(chuàng)建方法.png

總結(jié):

  1. 最常用的三個(gè)方法:decodeFile, decodeResource, decodeStream顷扩,前兩個(gè)最終調(diào)用的是 decodeStream;
  2. **decodeStream, decodeByteArray, decodeFileDescription **這三個(gè)內(nèi)部則調(diào)用的是 native 方法來(lái)創(chuàng)建 Bitmap的【有種說(shuō)法拐邪,Bitmap是Android中唯一通過(guò) native 方法創(chuàng)建的類(lèi)】;
  3. decodeResourceStream主要做了兩件事:一是對(duì) opts.inDensity 賦值屎即,沒(méi)有設(shè)置默認(rèn)值 160庙睡;二是對(duì) opts.inTargetDensity 賦值,沒(méi)有賦值為當(dāng)前設(shè)備 densityDpi技俐;
  4. decodeStream主要也做了兩件事:一是調(diào)用 native 方法解析 Bitmap乘陪;二是對(duì)解析得到的 Bitmap 調(diào)用 setDensityFraomOptions(bmp, opts) 進(jìn)行設(shè)置;
  5. setDensityFraomOptions(bmp, opts)主要做了這樣幾件事:一是當(dāng)opts.inDensity != opts.inTargetDensity || opts.inDensity != opts.inScreenDensity && (inScaled = true || isNinePatch) 時(shí)雕擂,將設(shè)置 outputBitmap.mDensity = inTargetDensity啡邑;

decodeResourceStream()方法源碼如下:

public static Bitmap decodeResourceStream(Resources res, TypedValue value,
            InputStream is, Rect pad, Options opts) {

        if (opts == null) {
            opts = new Options();
        }

        if (opts.inDensity == 0 && value != null) {
            final int density = value.density;
            if (density == TypedValue.DENSITY_DEFAULT) {
                opts.inDensity = DisplayMetrics.DENSITY_DEFAULT;
            } else if (density != TypedValue.DENSITY_NONE) {
                opts.inDensity = density;
            }
        }
        
        if (opts.inTargetDensity == 0 && res != null) {
            opts.inTargetDensity = res.getDisplayMetrics().densityDpi;
        }
        
        return decodeStream(is, pad, opts);
    }

setDensityFromOptions(bmp, opts)源碼如下:

private static void setDensityFromOptions(Bitmap outputBitmap, Options opts) {
        if (outputBitmap == null || opts == null) return;

        final int density = opts.inDensity;
        if (density != 0) {
            outputBitmap.setDensity(density);
            final int targetDensity = opts.inTargetDensity;
            if (targetDensity == 0 || density == targetDensity || density == opts.inScreenDensity) {
                return;
            }

            byte[] np = outputBitmap.getNinePatchChunk();
            final boolean isNinePatch = np != null && NinePatch.isNinePatchChunk(np);
            if (opts.inScaled || isNinePatch) {
                outputBitmap.setDensity(targetDensity);
            }
        } else if (opts.inBitmap != null) {
            // bitmap was reused, ensure density is reset
            outputBitmap.setDensity(Bitmap.getDefaultDensity());
        }
    }

三、如何計(jì)算Bitmap占用內(nèi)存大芯摹谤逼?

常規(guī)方式:
API方法:getByteCount() 獲取 - 不準(zhǔn)確

粗略方式:
計(jì)算公式:圖片長(zhǎng) * 寬 * 4bytes/ARG_8888 - 不正確

通讀源碼得來(lái)的方式:

    /**
     * Returns the minimum number of bytes that can be used to store this bitmap's pixels.
     *
     * <p>As of {@link android.os.Build.VERSION_CODES#KITKAT}, the result of this method can
     * no longer be used to determine memory usage of a bitmap. See {@link
     * #getAllocationByteCount()}.</p>
     */
    public final int getByteCount() {
        // int result permits bitmaps up to 46,340 x 46,340
        return getRowBytes() * getHeight();
    }
    /**
     * Return the number of bytes between rows in the bitmap's pixels. Note that
     * this refers to the pixels as stored natively by the bitmap. If you call
     * getPixels() or setPixels(), then the pixels are uniformly treated as
     * 32bit values, packed according to the Color class.
     *
     * <p>As of {@link android.os.Build.VERSION_CODES#KITKAT}, this method
     * should not be used to calculate the memory usage of the bitmap. Instead,
     * see {@link #getAllocationByteCount()}.
     *
     * @return number of bytes between rows of the native bitmap pixels.
     */
    public final int getRowBytes() {
        if (mRecycled) {
            Log.w(TAG, "Called getRowBytes() on a recycle()'d bitmap! This is undefined behavior!");
        }
        return nativeRowBytes(mNativePtr);
    }

最終通過(guò)native源碼方法,可得到:一張ARGB_8888 的Bitmap占用內(nèi)存計(jì)算公式:bmpWidth * bmpHeight * 4byte仇穗。不是直接使用圖片分辨率進(jìn)行計(jì)算流部,而是界面后 Bitmap 的寬高進(jìn)行計(jì)算。

然而纹坐,這樣計(jì)算并不準(zhǔn)確枝冀。有幾個(gè)不同的場(chǎng)景會(huì)導(dǎo)致最終計(jì)算的結(jié)果不正確。

  • 將一張 720x1080 圖片分別放在不同分辨率drawable文件夾下,在同一個(gè)手機(jī)上加載果漾;
  • 也是同一張圖片放在指定分辨率的 drawable 文件夾下球切,在不同手機(jī)上加載;
  • 切不同分辨率圖片到對(duì)應(yīng) drawable 文件夾下绒障,在各分辨率設(shè)備上加載吨凑。

一般,我們讀取 drawable 目錄下的圖片户辱,會(huì)用到 <code>decodeResource</code>獲取 Bitmap鸵钝,該方法可以直接看上面提到的 decodeResourceStream() 方法源碼,通過(guò)源碼可知:

  • 在讀取資源時(shí)庐镐,使用 openRawResource 方法蒋伦,然后會(huì)對(duì) TypedValue 進(jìn)行賦值,其中包含了原始資源的 density 等信息焚鹊,也即是文件夾代表的density痕届;
  • 調(diào)用 decodeResourceStream 對(duì)原始資源進(jìn)行解碼和適配,實(shí)際是原始資源 density 到 設(shè)備屏幕 density 的映射末患。

這里看一下 資源文件夾代表的密度:


資源文件夾密度對(duì)照表.png

對(duì)照 decodeResourceStream() 源碼如何設(shè)置 opts.inDensity 邏輯:


資源解碼Bitmap參數(shù)設(shè)置流程.png

最后通過(guò)查閱 native 源碼研叫,得到計(jì)算公式:
一張圖片對(duì)應(yīng) Bitmap 占用內(nèi)存 = mBitmapHeight * mBitmapWidth * 4byte(ARGB_8888);
Native 方法中璧针,mBitmapWidth = mOriginalWidth * (scale = opts.inTargetDensity / opts.inDensity) * 1/inSampleSize嚷炉,
mBitmapHeight = mOriginalHeight * (scale = opts.inTargetDensity / opts.inDensity) * 1/inSampleSize

現(xiàn)在針對(duì)介紹的幾種場(chǎng)景,會(huì)得到這樣的結(jié)論:

  1. 將一張 720x1080圖片放在 drawable-xhdpi 目錄下(inDensity = 320)探橱,
    • 在 720x1080 手機(jī)上加載(inTargetDensity = 320)申屹,圖片不會(huì)被壓縮;
    • 在 480x800 手機(jī)上加載(inTargetDensity = 240)隧膏,圖片會(huì)被壓縮 9/16哗讥;
    • 在 1080x1920 手機(jī)上加載(inTargetDensity = 480),圖片會(huì)被放大 2.25胞枕;
  2. 切不通分辨率大小的圖片放到對(duì)應(yīng)文件夾下杆煞,會(huì)根據(jù)屏幕獲取對(duì)應(yīng)文件夾的圖片,就不存在加載圖片時(shí)壓縮和放大(針對(duì)標(biāo)準(zhǔn)屏);

拓展問(wèn)題:只切一套UI圖腐泻,是否適用决乎?如何選擇?

注意派桩,上述計(jì)算方式是在通過(guò) decodeResource() 方法獲取 Bitmap 的情況下得出构诚,其他幾種方式獲取Bitmap,最后得到占用內(nèi)存Size不會(huì)跟資源文件目錄相關(guān)聯(lián)铆惑。

四范嘱、問(wèn)題解答

問(wèn)題一:一張圖片對(duì)應(yīng) Bitmap 占用內(nèi)存 = mBitmapHeight * mBitmapWidth * 4byte(ARGB_8888)凳寺;Native 方法中,mBitmapHeight = mOriginalHeight * (scale = opts.inTargetDensity / opts.inDensity) * 1/inSampleSize 彤侍;

由此可知,手機(jī)屏幕大小 1280 x 720(inTarget = 320)逆趋,加載 xxhdpi (inDensity = 480)中的圖片 1920 x 1080盏阶,scale = 320 / 480,inSampleSize = 1闻书,最終獲得的 Bitmap 的圖像大小是 :
mBitmapWidth = opts.outWidth = 1080 * (320 / 480) * 1/1 = 720名斟,
mBitmapHeight = opt.outHeight = 1920 * (320 / 480) * 1/1 = 1280,
getAllocatedMemory() = mBitmapWidth * mBitmapHeight * 4 = Bitmap占用內(nèi)存魄眉。

問(wèn)題三:使用 decodeResource() 和 decodeStream() 有什么區(qū)別砰盐?
(1)decodeResource() 流程,會(huì)先用 TypedValue 保存圖片信息坑律,然后會(huì)根據(jù)條件設(shè)置 opts.inDensity = value.inDensity岩梳,為0則設(shè)置為默認(rèn) 160dpi; 文件夾代表密度
Opts.inTargetDensity = getDisplayMetrics().densityDpi晃择; 屏幕密度
設(shè)置完上述參數(shù)后冀值,最終還是會(huì)調(diào)用 decodeStream() 方法;

(2)decodeStream() native 方法得到 Bitmap后宫屠,調(diào)用 setDensityFromOptions() 方法來(lái)設(shè)置 Bitmap.mDensity:
若 opts.inDensity != 0列疗,bitmap.mDensity = opts.inDensity;
若 opts.inTargetDensity != 0 && inDensity != targetDensity && inDensity != screenDensity,繼續(xù)判斷浪蹂,如果 opts.inScaled || isNinePatch抵栈,bitmap.mDensity = targetDensity;

所以,
(1)若使用 decodeResource() 加載本地圖片坤次,inDensity 為加載圖片所在的文件夾代表的 dpi古劲,inTargetDensity 為目標(biāo)屏幕密度(or 圖片真實(shí)像素密度?)缰猴,
最終 bitmap.mDensity = targetDensity绢慢。

(2)若使用 decodeStream() 則不會(huì)先記錄圖片信息,得到bitmap 后洛波,直接調(diào)用 setDensityFromOptions() 方法胰舆,所以最終 bitmap.mDensity = defaultDensity() = DENSITY_DEVICE。

參考源碼API-26
參考:http://dev.qq.com/topic/591d61f56793d26660901b4e
???????????https://www.tuicool.com/articles/3eMNr2n
如有誤蹬挤,請(qǐng)指正缚窿!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市焰扳,隨后出現(xiàn)的幾起案子倦零,更是在濱河造成了極大的恐慌误续,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扫茅,死亡現(xiàn)場(chǎng)離奇詭異蹋嵌,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)葫隙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)栽烂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人恋脚,你說(shuō)我怎么就攤上這事腺办。” “怎么了糟描?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵怀喉,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我船响,道長(zhǎng)躬拢,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任见间,我火速辦了婚禮估灿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘缤剧。我一直安慰自己馅袁,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布荒辕。 她就那樣靜靜地躺著汗销,像睡著了一般。 火紅的嫁衣襯著肌膚如雪抵窒。 梳的紋絲不亂的頭發(fā)上弛针,一...
    開(kāi)封第一講書(shū)人閱讀 49,007評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音李皇,去河邊找鬼削茁。 笑死,一個(gè)胖子當(dāng)著我的面吹牛掉房,可吹牛的內(nèi)容都是我干的茧跋。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼卓囚,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼瘾杭!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起哪亿,我...
    開(kāi)封第一講書(shū)人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤粥烁,失蹤者是張志新(化名)和其女友劉穎贤笆,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體讨阻,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡芥永,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了钝吮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片埋涧。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖搀绣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情戳气,我是刑警寧澤链患,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站瓶您,受9級(jí)特大地震影響麻捻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜呀袱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一贸毕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧夜赵,春花似錦明棍、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至嘁傀,卻和暖如春兴蒸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背细办。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工橙凳, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人笑撞。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓岛啸,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親茴肥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子值戳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 2021期待與你一起共事,點(diǎn)擊查看崗位[http://www.reibang.com/p/6f4d67fa406...
    閑庭閱讀 16,609評(píng)論 0 75
  • 一直以來(lái)Bitmap都是開(kāi)發(fā)中很棘手的問(wèn)題炉爆,這個(gè)問(wèn)題就是傳說(shuō)中的OOM(java.lang.OutofMemory...
    M悇芐冋憶閱讀 4,702評(píng)論 0 11
  • 一堕虹、Bitmap 內(nèi)存回收 從3.0開(kāi)始卧晓,Bitmap 像素?cái)?shù)據(jù)和 Bitmap 對(duì)象一起存放在 Dalvik 堆...
    秀花123閱讀 1,819評(píng)論 1 7
  • 表嫂有四個(gè)兒子赦政,她姐沒(méi)小孩生胜宇,就送了老二給她養(yǎng)。七十年代那時(shí)都是吃大鍋飯恢着,一早大家就一起出工桐愉,每天都要完成那么多分...
    素顏抺淡妝閱讀 372評(píng)論 0 2
  • 將所讀的文字信息轉(zhuǎn)化為你的文字和術(shù)語(yǔ),變成你的理解和語(yǔ)言掰派,就成為了你自己的書(shū)从诲。這就是讀書(shū),讀書(shū)并不是記憶靡羡,而是某些...
    行者之龍閱讀 134評(píng)論 0 0