探索 Android 内存优化方法( 三 )


4.2.1 前台进程
前台进程(Foreground Process)是优先级最高的进程 , 是正在于用户交互的进程 , 如果满足下面一种情况 , 则一个进程被认为是前台进程 。

  1. Activity 进程持有一个与用户交互的 Activity(该 Activity 的 onResume 方法被调用)
  2. 进程持有一个 Service , 并且这个 Service 处于下面几种状态之一
  • Service 与用户正在交互的 Activity 绑定
  • Service 调用了 startForeground 方法
  • Service 正在执行以下生命周期函数(onCreate、onStart、onDestroy )
  1. BroadcastReceiver 进程持有一个 BroadcastReceiver , 这个 BroadcastReceiver 正在执行它的 onReceive 方法
4.2.2 可见进程
可见进程(Visible Process)不含有任何前台组件 , 但用户还能再屏幕上看见它 , 当满足一下任一条件时 , 进程被认定是可见进程 。
  1. Activity 进程持有一个 Activity , 这个 Activity 处于 pause 状态 , 比如前台 Activity 打开了一个对话框 , 这样后面的 Activity 就处于 pause 状态
  2. Service 进程持有一个 Service 这个 Service 和一个可见的 Activity 绑定 。
可见进程是非常重要的进程 , 除非前台进程已经把系统的可用内存耗光 , 否则系统不会终止可见进程 。
4.2.3 服务进程
服务进程(Service Process)可能在播放音乐或在后台下载文件 , 除非系统内存不足 , 否则系统会尽量维持服务进程的运行 。
当一个进程满足下面一个条件时 , 系统会认定它为服务进程 。
  1. Service 如果一个进程中运行着一个 Service , 并且这个 service 是通过 startService 开启的 , 那这个进程就是一个服务进程 。
4.2.4 后台进程
当一个进程满足下面条件时 , 系统会认定它为后台进程 。
  1. Activity 当进程持有一个用户不可见的 Activity(Activity 的 onStop 方法被调用) , 但是 onDestroy 方法没有被调用 , 这个进程就会被系统认定为后台进程 。
系统会把后台进程保存在一个 LruCache 列表中 , 因为终止后台进程对用户体验影响不大 , 所以系统会酌情清理部分后台进程 。
你可以在 Activity 的 onSaveInstanceState 方法中保存一些数据 , 以免在应用被系统清理掉后 , 用户已输入的信息被清空 , 导致要重新输入 。
4.2.5 空进程
当一个进程不包含任何活跃的应用组件 , 则被系统认定为是空进程 。
系统保留空进程的目的是为了加快下次启动进程的速度 。
5. 图片对内存有什么影响?
大部分 App 都免不了使用大量的图片 , 比如电商应用和外卖应用等 。
图片在 Android 中对应的是 Bitmap 和 Drawable 类 , 我们从网络上加载下来的图片最终会转化为 Bitmap 。
图片会消耗大量内存 , 如果使用图片不当 , 很容易就会造成 OOM 。
下面我们来看下 Bitmap 与内存有关的一些内容 。
5.1 获取 Bitmap 占用的内存大小
  1. Bitmap.getByteCount Bitmap 提供了一个 getByteCount 方法获取图片占用的内存大小 , 但是这个方法只能在程序运行时动态计算 。
  2. 图片内存公式 图片占用内存公式:宽 * 高 * 一个像素占用的内存 。假如我们现在有一张 2048 * 2048 的图片 , 并且编码格式为 ARGB_8888 , 那么这个图片的大小为 2048 * 2048 * 4 = 16, 777, 216 个字节 , 也就是 16M 。如果厂商给虚拟机设置的堆大小是 256M , 那么像这样的图片 , 应用最极限的情况只能使用 16 张 。我们的应用在运行时 , 不仅仅是我们自己写的代码需要消耗内存 , 还有库中创建的对象同样需要占用堆内存 , 也就是别说 16 张 , 多来几张应用就挂了 。
5.2 Bitmap 像素大小
一张图片中每一个像素的大小取决于它的解码选项 , 而 Android 中能够选择的 Bitmap 解码选项有四种 。
下面四种解码选项中的的 ARGB 分别代表透明度和三原色 Alpha、Red、Green、Blue 。
  1. ARGB_8888 ARGB 四个通道的值都是 8 位 , 加起来 32 位 , 也就是每个像素占 4 个字节
  2. ARGB_4444 ARGB 四个通道的值都是 4 位 , 加起来 16 位 , 也就是每个像素占 2 个字节
  3. RGB_565 RGB 三个通道分别是 5 位、6 位、5 位 , 加起来 16 位 , 也就是每个像素占 2 个字节


    推荐阅读