Android處理大圖避免OOM的完整方案
1. 計(jì)算合適的縮放比例
使用 BitmapFactory.Options
的 inSampleSize
對(duì)圖片進(jìn)行采樣壓縮:
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { final int width = options.outWidth; final int height = options.outHeight; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { final int halfWidth = width / 2; final int halfHeight = height / 2; while ((halfWidth / inSampleSize) >= reqWidth && (halfHeight / inSampleSize) >= reqHeight) { inSampleSize *= 2; } } return inSampleSize; }
2. 分步加載圖片
- 步驟 1:僅讀取圖片尺寸(不分配內(nèi)存)
BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(getResources(), R.drawable.large_image, options); int imageWidth = options.outWidth; int imageHeight = options.outHeight;
- 步驟 2:動(dòng)態(tài)計(jì)算縮放比例并加載
options.inJustDecodeBounds = false; options.inSampleSize = calculateInSampleSize(options, targetWidth, targetHeight); Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.large_image, options);
3. 優(yōu)化內(nèi)存配置
使用更低的像素格式(如不需要透明度):
options.inPreferredConfig = Bitmap.Config.RGB_565; // 每個(gè)像素占 2 字節(jié)(內(nèi)存減半)
禁用自動(dòng)縮放(避免系統(tǒng)根據(jù)屏幕密度調(diào)整大?。?/p>
options.inScaled = false;
4. 按需加載局部區(qū)域(超大圖場景)
使用 BitmapRegionDecoder
分塊加載:
InputStream is = getAssets().open("large_image.jpg"); BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(is, false); Rect rect = new Rect(startX, startY, startX + width, startY + height); Bitmap bitmap = decoder.decodeRegion(rect, options);
5. 及時(shí)回收資源
在 onDestroy()
或不再需要 Bitmap 時(shí)主動(dòng)回收:
if (bitmap != null && !bitmap.isRecycled()) { bitmap.recycle(); bitmap = null; }
避免在 onDraw()
中頻繁創(chuàng)建 Bitmap(利用緩存或復(fù)用機(jī)制)。
6. 使用第三方庫(推薦)
Glide:自動(dòng)處理圖片縮放、內(nèi)存/磁盤緩存、生命周期管理。
Glide.with(context) .load("path/to/image") .override(targetWidth, targetHeight) .into(imageView);
Picasso:類似 Glide,提供簡潔的 API 管理大圖。
7. 配置大堆或硬件加速
在 AndroidManifest.xml
中為 Activity 添加 largeHeap="true"
(臨時(shí)緩解,不推薦長期依賴):
<application android:largeHeap="true">
啟用硬件加速(在部分場景下減少內(nèi)存壓力):
<activity android:hardwareAccelerated="true" />
關(guān)鍵公式:內(nèi)存估算
內(nèi)存占用 = 圖片寬度 * 圖片高度 * 每像素字節(jié)數(shù) 例如:4000x3000 的 ARGB_8888 圖片 = 4000 * 3000 * 4B ≈ 48MB
通過上述策略,可顯著降低內(nèi)存占用,有效避免 OOM。實(shí)際開發(fā)中優(yōu)先使用 Glide/Picasso 等成熟庫,減少手動(dòng)處理風(fēng)險(xiǎn)。
以上就是Android處理大圖避免OOM的完整方案的詳細(xì)內(nèi)容,更多關(guān)于Android處理大圖避免OOM的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android webview 遇到android.os.FileUriExposedException錯(cuò)誤解決辦法
這篇文章主要介紹了Android webview 遇到android.os.FileUriExposedException錯(cuò)誤解決辦法的相關(guān)資料,希望通過本文能幫助到大家,讓大家遇到這樣的問題解決,需要的朋友可以參考下2017-10-10Android自定義View實(shí)現(xiàn)跟隨手指移動(dòng)
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)跟隨手指移動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08Android實(shí)現(xiàn)3D標(biāo)簽云簡單效果
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)3D標(biāo)簽云簡單效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05Android檢查手機(jī)有沒有安裝某應(yīng)用的方法
這篇文章主要介紹了Android檢查手機(jī)有沒有安裝某應(yīng)用的方法,分析總結(jié)了幾種常用的判斷技巧,涉及Android針對(duì)應(yīng)用程序包的相關(guān)讀取與判定技巧,需要的朋友可以參考下2016-08-08Kotlin RadioGroup與ViewPager實(shí)現(xiàn)底層分頁按鈕方法
安卓的控件是挺多的,沒有辦法一個(gè)一個(gè)的來說明,我們挑出了一些重點(diǎn)的控件,組成一些常見的布局,這樣以后在遇到相同功能的界面時(shí),就會(huì)有自己的思路,或者進(jìn)行復(fù)用2022-12-12Android APK使用Debug簽名重新打包 Eclipse更改默認(rèn)Debug簽名
這篇文章主要介紹了Android APK使用Debug簽名重新打包 Eclipse更改默認(rèn)Debug簽名等內(nèi)容,需要的朋友可以參考下2015-04-04