Learn how to use common techniques to process and loadBitmap
objects in a way that keeps your user interface (UI) components responsive and avoids exceeding your application memory limit. If you’re not careful, bitmaps can quickly consume your available memory budget leading to an application crash due to the dreaded exception:
java.lang.OutofMemoryError: bitmap size exceeds VM budget
.
There are a number of reasons why loading bitmaps in your Android application is tricky:
- Mobile devices typically have constrained system resources. Android devices can have as little as 16MB of memory available to a single application. TheAndroid Compatibility Definition Document (CDD),Section 3.7. Virtual Machine Compatibility gives the required minimum application memory for various screen sizes and densities. Applications should be optimized to perform under this minimum memory limit. However, keep in mind many devices are configured with higher limits.
- Bitmaps take up a lot of memory, especially for rich images like photographs. For example, the camera on the Galaxy Nexus takes photos up to 2592×1936 pixels (5 megapixels). If the bitmap configuration used is
ARGB_8888
(the default from the Android 2.3 onward) then loading this image into memory takes about 19MB of memory (2592*1936*4 bytes), immediately exhausting the per-app limit on some devices. - Android app UI’s frequently require several bitmaps to be loaded at once. Components such as
ListView
,GridView
andViewPager
commonly include multiple bitmaps on-screen at once with many more potentially off-screen ready to show at the flick of a finger.
译:上面的一段话主要就是说bitmap会很快消耗内存,导致OOM。并且列举个几个原因。
- 移动设备的系统资源有限。Android设备对于单个程序至少需要16MB的内存。Android Compatibility Definition Document (CDD), Section 3.7. Virtual Machine Compatibility 给出了对于不同大小与密度的屏幕的最低内存需求。 程序应该在这个最低内存限制下最优化程序的效率。当然,大多数设备的都有更高的限制需求。
- Bitmap会消耗很多内存,特别是对于类似照片等内容更加丰富的图片。 例如,Galaxy Nexus的照相机能够拍摄2592×1936 pixels (5 MB)的图片。 如果bitmap的配置是使用ARGB_8888 (从Android 2.3开始的默认配置) ,那么加载这张照片到内存会大概需要19MB(
2592*1936*4
bytes) 的内存, 这样的话会迅速消耗掉设备的整个内存。 - Android app的UI通常会在一次操作中立即加载许多张bitmaps。 例如在ListView, GridView 与ViewPager 等组件中通常会需要一次加载许多张bitmaps,而且需要预先加载一些没有在屏幕上显示的内容,为用户滑动时显示做准备。
Lessons
-
Loading Large Bitmaps Efficiently
- This lesson walks you through decoding large bitmaps without exceeding the per application memory limit. Processing Bitmaps Off the UI Thread
-
Bitmap processing (resizing, downloading from a remote source, etc.) should never take place on the main UI thread. This lesson walks you through processing bitmaps in a background thread using
AsyncTask
and explains how to handle concurrency issues.
Caching Bitmaps
- This lesson walks you through using a memory and disk bitmap cache to improve the responsiveness and fluidity of your UI when loading multiple bitmaps. Managing Bitmap Memory
- This lesson explains how to manage bitmap memory to maximize your app’s performance. Displaying Bitmaps in Your UI
-
This lesson brings everything together, showing you how to load multiple bitmaps into components like
ViewPager
andGridView
using a background thread and bitmap cache. -
译:
- 高效的加载大图(Loading Large Bitmaps Efficiently)这节课会带领你学习如何解析很大的Bitmaps并且避免超出程序的内存限制。
- 非UI线程处理Bitmap(Processing Bitmaps Off the UI Thread)
处理Bitmap(裁剪,下载等操作)不能执行在主线程。这节课会带领你学习如何使用AsyncTask在后台线程对Bitmap进行处理,并解释如何处理并发带来的问题。
- 缓存Bitmaps(Caching Bitmaps)
这节课会带领你学习如何使用内存与磁盘缓存来提升加载多张Bitmaps时的响应速度与流畅度。
- 管理Bitmap占用的内存(Managing Bitmap Memory)
这节课会介绍为了最大化程序的性能如何管理Bitmap的内存占用。
- 在UI上显示Bitmap(Displaying Bitmaps in Your UI)
这节课会把前面介绍的内容综合起来,演示如何在类似ViewPager与GridView的控件中使用后台线程与缓存进行加载多张Bitmaps。