首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android ScrollView 設定背景圖導致 OOM 解決方案

     編輯:程式設計綜合問答

現象:在 `ScrollView` 或其子 `Layout` 設定 `android:background="@drawable/large_image"`,App 啟動瞬間崩潰,Logcat 顯示 `OutOfMemoryError`。

根因

背景圖解析度過高(如 3000×4000 px),解碼後佔用記憶體 = 寬 × 高 × 4 bytes ≈ 48 MB,超過單進程記憶體上限(舊設備 16-24 MB,新設備 192-512 MB),且 `ScrollView` 不支援 `android:tileMode` 平鋪,會嘗試一次性載入完整圖片。

解決方案(按推薦順序)

1. 降低圖片解析度(最直接)

  • 設計圖按螢幕寬度輸出(如 1080px 寬),高度按比例縮放。
  • 使用 WebP 格式(無損/有損),體積減少 30%+。

2. 程式碼動態載入並縮放

// 在 Activity/Fragment onCreate 中
ScrollView scrollView = findViewById(R.id.scrollView);
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.drawable.bg_image, opts);
// 計算縮放比例,目標寬度 = 螢幕寬度
opts.inSampleSize = calculateInSampleSize(opts, screenWidth, 0);
opts.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bg_image, opts);
scrollView.setBackground(new BitmapDrawable(getResources(), bitmap));

3. 使用可平鋪的小圖

<bitmap xmlns:android="https://schemas.android.com/apk/res/android"
    android:src="@drawable/small_pattern"
    android:tileMode="repeat"
    android:dither="true" />

在 `ScrollView` 設定 `android:background="@drawable/tiled_bg"`,記憶體佔用極小。

4. 分塊載入大圖(進階)

將大圖切割為多張小圖,使用 `RecyclerView` + `GridLayoutManager` 惰性載入,或使用 Subsampling Scale Image View 庫。

最佳實踐清單

  • ✅ 所有 `drawable` 資源放入 `drawable-xxhdpi`/`drawable-xxxhdpi`,避免系統自動放大。
  • ✅ 啟用 `android:largeHeap="true"`(Application 標籤)僅作為臨時緩解,不可依賴。
  • ✅ 使用 Glide/Picasso 載入網路圖片時自動縮放至 `ImageView` 尺寸。
  • ✅ 定期用 Android Profiler → Memory 檢查 Bitmap 記憶體佔用。

核心原則:背景圖解析度不超過螢幕解析度,優先使用可平鋪小圖或程式碼縮放載入。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved