| 方案 | API Level | 核心代碼 | 適用場景 |
| inSampleSize 亞採樣 | 所有 | opts.inSampleSize = calculateInSampleSize(opts, reqW, reqH); | 縮略圖、列表展示 |
| inBitmap 復用 (舊) | 11-18 | opts.inBitmap = reusableBitmap; | 舊版本適配 |
| LruCache + 異步加載 | 12+ (推薦) | Glide/Picasso/Coil 庫一行代碼 | 生產項目標配 |
| decodeStream 避免 Java 層拷貝 | 所有 | BitmapFactory.decodeStream(is, null, opts) | 手動優化 |
推薦:接入圖片加載庫 (Glide 4.x)
// build.gradle
implementation 'com.github.bumptech.glide:glide:4.16.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'
// 使用
Glide.with(this)
.load(R.drawable.img01) // 或 URL/File/Uri
.override(360, 240) // 目標尺寸,自動計算 inSampleSize
.placeholder(R.drawable.placeholder)
.error(R.drawable.error)
.into(imageView);
手動優化代碼 (不引入庫)
public static Bitmap decodeSampledBitmap(Resources res, int resId, int reqW, int reqH) {
// 1. 僅解碼邊界
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, opts);
// 2. 計算最佳 inSampleSize (2的冪次)
opts.inSampleSize = calculateInSampleSize(opts, reqW, reqH);
// 3. 真實解碼
opts.inJustDecodeBounds = false;
opts.inPreferredConfig = Bitmap.Config.RGB_565; // 节省50%内存
return BitmapFactory.decodeResource(res, resId, opts);
}
static int calculateInSampleSize(BitmapFactory.Options opts, int reqW, int reqH) {
int inSampleSize = 1;
if (opts.outHeight > reqH || opts.outWidth > reqW) {
int halfH = opts.outHeight / 2;
int halfW = opts.outWidth / 2;
while ((halfH / inSampleSize) >= reqH && (halfW / inSampleSize) >= reqW)
inSampleSize *= 2;
}
return inSampleSize;
}
// 在 Activity 中使用
for (int i = 0; i < 4; i++) {
Bitmap bmp = decodeSampledBitmap(getResources(), imagePath[i], 360, 240);
img[i].setImageBitmap(bmp);
// 重要:Activity 銷毀時 recycle()
// 或維護 LruCache 復用
}
內存監控與調試
- Android Studio Profiler → Memory 實時觀察堆變化。
adb shell dumpsys meminfo 包名 查看 PSS/Private Dirty。
- 開啟
Developer Options → Show GPU Overdraw / Debug GPU Overdraw 檢測過度繪制。
總結
- **不要直接 setImageResource 大圖**,必須亞採樣或用庫。
- **生產項目直接用 Glide/Coil**,自動處理緩存、生命周期、圖片請求合併、GIF、轉換。
- 測試時**調大 AVD/真機內存**,或用
android:largeHeap="true" (慎用)。
- 上一篇文章: STM32F4 USB + SPI 數據傳輸開發指南:分模塊調試法
- 下一篇文章: 二叉樹創建與遍歷:運行時輸入指南
Copyright ©
程式碼之家 All Rights Reserved