APP的優化是任重而道遠的過程,必須在意每一個環節,否者當你想要優化的時候,發現到處都是坑,已經不知道填補哪里了,所以我們必須一點一滴的做起。
Bitmap
Bitmap的內存管理優化
大量Bitmap的創建和垃圾回收,會產生內存抖動,引發卡頓。一次性加載超大的圖片會導致OOM,所以我們要避免或者合理的使用循環縮放,壓縮,縮放的目的主要是合理的使用(避免大圖加載OOM,因為手機實際是用不到那么大的圖片的)。或者使用一些比較好的第三方工具如Glide。(不要懷疑bitmap的優化就是這么一句。)
Bitmap相關方法總結
public void recycle() // 回收位圖占用的內存空間,把位圖標記為Dead
public final boolean isRecycled() //判斷位圖內存是否已釋放
public final int getWidth() //獲取位圖的寬度
public final int getHeight() //獲取位圖的高度
public final boolean isMutable() //圖片是否可修改
public int getScaledWidth(Canvas canvas) //獲取指定密度轉換后的圖像的寬度
public int getScaledHeight(Canvas canvas) //獲取指定密度轉換后的圖像的高度
public boolean compress(CompressFormat format, int quality, OutputStreamstream) //按指定的圖片格式以及畫質,將圖片轉換為輸出流
public static Bitmap createBitmap(Bitmap src) //以 src 為原圖生成不可變得新圖像
public static Bitmap createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter) //以 src 為原圖,創建新的圖像,指定新圖像的高寬以及是否可變。
public static Bitmap createBitmap(int width, int height, Config config) //創建指定格式、大小的位圖
public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height) //以 source 為原圖,創建新的圖片,指定起始坐標以及新圖像的高寬。
BitmapFactory工廠類
Option 參數類
public boolean inJustDecodeBounds
//如果設置為 true ,不獲取圖片,不分配內存,但會返回圖片的高度寬度信息。如果將這個值置為 true ,那么在解碼的時候將不會返回 bitmap ,只會返回這個 bitmap 的尺寸。這個屬性的目的是,如果你只想知道一個 bitmap 的尺寸,但又不想將其加載到內存時。這是一個非常有用的屬性。
public int inSampleSize
?//圖片縮放的倍數, 這個值是一個 int ,當它小于1的時候,將會被當做1處理,如果大于1,那么就會按照比例 (1 / inSampleSize) 縮小 bitmap 的寬和高、降低分辨率,大于1時這個值將會被處置為2的倍數。例如, width=100,height=100,inSampleSize=2 ,那么就會將 bitmap 處理為, width=50,height=50 ,寬高降為1 / 2,像素數降為1 / 4。
public int outWidth //獲取圖片的寬度值
public int outHeight //獲取圖片的高度值 ,表示這個 Bitmap 的寬和高,一般和
inJustDecodeBounds 一起使用來獲得 Bitmap 的寬高,但是不加載到內存。
public int inDensity //用于位圖的像素壓縮比
public int inTargetDensity //用于目標位圖的像素壓縮比(要生成的位圖)
public byte[] inTempStorage //創建臨時文件,將圖片存儲
public boolean inScaled //設置為 true 時進行圖片壓縮,從 inDensity 到inTargetDensity
public boolean inDither //如果為 true ,解碼器嘗試抖動解碼
public Bitmap.Config inPreferredConfig //設置解碼器,這個值是設置色彩模式,默認值是 ARGB_8888 ,在這個模式下,一個像素點占用4bytes空間,一般對透明度不做要求的話,一般采用 RGB_565 模式,這個模式下一個像素點占用2bytes。
public String outMimeType //設置解碼圖像
public boolean inPurgeable //當存儲 Pixel 的內存空間在系統內存不足時是否可以被回收
public boolean inInputShareable // inPurgeable 為 true 情況下才生效,是否可以共享一個 InputStream
public boolean inPreferQualityOverSpeed //為 true 則優先保證 Bitmap 質量其次是解碼速度
public boolean inMutable //配置 Bitmap 是否可以更改,比如:在 Bitmap 上隔幾個像素加一條線段
public int inScreenDensity//當前屏幕的像素密度
工廠方法
public static Bitmap decodeFile(String pathName, Options opts) //從文件讀取圖片
public static Bitmap decodeFile(String pathName)
public static Bitmap decodeStream(InputStream is) //從輸入流讀取圖片
public static Bitmap decodeStream(InputStream is, Rect outPadding, Optionsopts)
public static Bitmap decodeResource(Resources res, int id) //從資源文件讀取圖片
public static Bitmap decodeResource(Resources res, int id, Options opts)
public static Bitmap decodeByteArray(byte[] data, int offset, int length) //從數組讀取圖片
public static Bitmap decodeByteArray(byte[] data, int offset, int length,Options opts)
public static Bitmap decodeFileDescriptor(FileDescriptor fd) //從文件讀取文件 與decodeFile 不同的是這個直接調用JNI函數進行讀取 效率比較高
public static Bitmap decodeFileDescriptor(FileDescriptor fd, Rect outPadding,Options opts)
單個像素的字節大小
單個像素的字節大小由Bitmap的一個可配置的參數Config來決定。
Bitmap中,存在一個枚舉類Config,定義了Android中支持的Bitmap配置:
Bitmap加載方式
Bitmap 的加載方式有 Resource 資源加載、本地(SDcard)加載、網絡加載等加載方式。(詳細不細說)
Bitmap的內存回收
使用Bitmap.recycle()方法進行Bitmap的內存回收。
drawable圖片加載放置
圖片放在某個特定drawable中,比如drawable-hdpi,如果設備的屏幕密度高于當前drawable目錄所代表的密度,則圖片會被放大,否則會被縮小放大或縮小比例 = 設備屏幕密度 / drawable目錄所代表的屏幕密度。
Bitmap長圖加載
思路,通過獲取需要加載的部分高寬:使用decodeRegion區域加載,使用BigmapRegionDecoder流方式加載,對圖像進行部分加載。