關於Bitmap中的inBitmap變量的學習與使用

inBitmap是在BitmapFactory中的內部類Options的一個變量,簡單而言,使用該變量能夠複用舊的Bitmap的內存而不用從新分配以及銷燬舊Bitmap,進而改善運行效率。html

關於Bitmap的相關知識能夠查看我寫的Android中Bitmap的深刻探討總結java

inBitmap知識點

inBitmap變量是在Android 3.0+版本加入到系統源碼當中,也就意味着inBitmap參數只有在Android 3.0+版本及以上可以正常使用,當你的app版本低於3.0的時候,仍是老老實實的使用bitmap.recycle()進行Bitmap的回收操做;在Android 3.0+以上根據系統版本的不一樣,使用inBitmap的規則也不相同,具體區分以下:android

  • 4.4以前的版本inBitmap只可以重用相同大小的Bitmap內存區域。簡單而言,被重用的Bitmap須要與新的Bitmap規格徹底一致,不然不能重用。
  • 4.4以後的版本系統再也不限制舊Bitmap與新Bitmap的大小,只要保證舊Bitmap的大小是大於等於新Bitmap大小便可。

除上述規則以外,舊Bitmap必須是mutable的,這點也很好理解,若是一個Bitmap不支持修改,那麼其內存天然也重用不了。Ok,關於inBitmap的知識點理論上也就那麼多。Google爲了幫助咱們更好的管理Bitmap,也出了一個視頻,視頻地址以下:緩存

https://www.youtube.com/watch?v=_ioFW3cyRV0&index=17&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCEapp

而且附帶上了一個使用inBitmap的Demo:框架

https://developer.android.com/topic/performance/graphics/manage-memory.html#javaide

下面貼視頻中兩張圖更好的幫助一下理解:ui

使用inBitmap以前:.net

使用inBitmap以後:設計

inBitmap的疑問

針對上述的理解,這裏有一個疑問須要去確認一下:

  • inBitmap的解碼模式跟新Bitmap的不一樣是否可以重用成功

解決這個疑問能夠查看Google官方的inBitmap Demo來回答問題:

/**
  * candidate:舊的圖片,targetOptions:新的圖片的Options
  */
private fun canUseForInBitmap(candidate: Bitmap, targetOptions: BitmapFactory.Options): Boolean {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        // From Android 4.4 (KitKat) onward we can re-use if the byte size of
        // the new bitmap is smaller than the reusable bitmap candidate
        // allocation byte count.
        val width: Int = targetOptions.outWidth / targetOptions.inSampleSize
        val height: Int = targetOptions.outHeight / targetOptions.inSampleSize
        val byteCount: Int = width * height * getBytesPerPixel(candidate.config)
        byteCount <= candidate.allocationByteCount
    } else {
        // On earlier versions, the dimensions must match exactly and the inSampleSize must be 1
        candidate.width == targetOptions.outWidth
                && candidate.height == targetOptions.outHeight
                && targetOptions.inSampleSize == 1
    }
}

/**
 * A helper function to return the byte usage per pixel of a bitmap based on its configuration.
 */
private fun getBytesPerPixel(config: Bitmap.Config): Int {
    return when (config) {
        Bitmap.Config.ARGB_8888 -> 4
        Bitmap.Config.RGB_565, Bitmap.Config.ARGB_4444 -> 2
        Bitmap.Config.ALPHA_8 -> 1
        else -> 1
    }
}

這裏能夠看出,只要新的Bitmap的內存小於舊Bitmap的內存大小,便可進行復用的操做,那麼跟解碼模式沒有必然的聯繫。

inBitmap的使用

關於inBitmap的使用,能夠根據谷歌的官方例子進行設計和開發,不過維護起來須要必定的工做量。固然在市面上成熟的圖片框架中,如Glide內部也使用了inBitmap做爲緩存複用的一種方式。總而言之,根據項目以及業務來選擇實現方式便可,沒必要過度糾結。

相關文章
相關標籤/搜索