最新消息:

Android 内存优化

PHP PHPaihaozhe 128浏览 0评论

Android 内存优化

优化方案

检查使用多少内存

每个 APP 的堆(heap)内存大小有硬性限制,如果您的 APP 已达到堆内存限制,并尝试分配更多的内存,系统会抛出 OutOfMemoryError 。为了避免 OOM ,您可以查询当前设备有多少堆空间,可以通过调用系统 getMemoryInfo() 查询,返回 一个ActivityManager.MemoryInfo 对象,它提供该设备当前存储器的状态信息,包括可用的存储器,总存储器,和低于该阈值存储器。

private void getMemoryInfo() {

ActivityManager activityManager = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);

ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();

activityManager.getMemoryInfo(memoryInfo);

LogUtil.d(“totalMem=” + memoryInfo.totalMem + “,availMem=” + memoryInfo.availMem);

if (!memoryInfo.lowMemory) {

// 运行在低内存环境

}

}

当界面不可见时释放内存

实现 ComponentCallbacks2 API 中 onTrimMemory()) ,当回调参数 level 为 TRIM_MEMORY_UI_HIDDEN ,是用户点击了Home键或者Back键退出应用,所有UI界面被隐藏,这时候应该释放一些不可见的时候非必须的资源。

public class MainActivity extends AppCompatActivity

implements ComponentCallbacks2 {

// Other activity code ...

/**

* Release memory when the UI becomes hidden or when system resources become low.

* @param level the memory-related event that was raised.

*/

public void onTrimMemory(int level) {

// Determine which lifecycle or system event was raised.

switch (level) {

case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:

/*

Release any UI objects that currently hold memory.

The user interface has moved to the background.

*/

break;

case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:

case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:

case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:

/*

Release any memory that your app doesn’t need to run.

The device is running low on memory while the app is running.

The event raised indicates the severity of the memory-related event.

If the event is TRIM_MEMORY_RUNNING_CRITICAL, then the system will

begin killing background processes.

*/

break;

case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:

case ComponentCallbacks2.TRIM_MEMORY_MODERATE:

case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:

/*

Release as much memory as the process can.

The app is on the LRU list and the system is running low on memory.

The event raised indicates where the app sits within the LRU list.

If the event is TRIM_MEMORY_COMPLETE, the process will be one of

the first to be terminated.

*/

break;

default:

/*

Release any non-critical data structures.

The app received an unrecognized memory level value

from the system. Treat this as a generic low-memory message.

*/

break;

}

}

}

该 onTrimMemory() 回调是在搭载Android 4.0(API级别14)加入。对于早期版本,您可以使用 onLowMemory() 回调作为旧版本的回调,这大致相当于 TRIM_MEMORY_COMPLETE事件。

谨慎使用服务

离开了 APP 还在运行服务是最糟糕的内存管理错误之一,当 APP 处在后台,我们应该停止服务,除非它需要运行的任务。我们可以使用 JobScheduler 替代实现,JobScheduler 把一些不是特别紧急的任务放到更合适的时机批量处理。如果必须使用一个服务,最佳方法是使用 IntentService ,限制服务寿命,所有请求处理完成后,IntentService 会自动停止。

使用优化的数据容器

考虑使用优化过数据的容器 SparseArray / SparseBooleanArray / LongSparseArray 代替 HashMap 等传统数据结构,通用 HashMap 的实现可以说是相当低效的内存,因为它需要为每个映射一个单独的条目对象。

避免在 Android 上使用枚举

枚举往往需要两倍多的内存,静态常量更多,我们应该严格避免在 Android 上使用枚举。

使用 nano protobufs 序列化数据

Protocol buffers 是一个语言中立,平台中立的,可扩展的机制,由谷歌进行序列化结构化数据,类似于 XML 设计的,但是更小,更快,更简单。如果需要为您的数据序列化与协议化,建议使用 nano protobufs。

避免内存流失

内存流失可能会导致出现大量的 GC 事件,如自定义组件的 onDraw() ,避免大量创建临时对象,比如 String ,以免频繁触发 GC。GC 事件通常不影响您的 APP 的性能,然而在很短的时间段,发生许多垃圾收集事件可以快速地吃了您的帧时间,系统上时间的都花费在 GC ,就有很少时间做其他的东西像渲染或音频流。

使用ProGuard来剔除不需要的代码

使用 ProGuard 来剔除不需要的代码,移除任何冗余的,不必要的,或臃肿的组件,资源或库完善 APP 的内存消耗。

降低整体尺寸APK

您可以通过减少 APP 的整体规模显著减少 APP 的内存使用情况。文章:Android APK瘦身实践

优化布局层次

通过优化视图层次结构,以减少重叠的 UI 对象的数量来提高性能。文章:Android 渲染优化

使用 Dagger 2依赖注入

依赖注入框架可以简化您写的代码,并提供一个自适应环境测试和便于其他配置的更改。如果打算在您的 APP 使用依赖注入框架,可以考虑用 Dagger 2 ,Dagger 不使用反射扫描 APP 的代码,Dagger 是静态的,意味着它编译时不需要占用运行 Android 应用或内存的使用。

请小心使用外部库

外部库的代码往往是未针对移动环境下编写并用于工作在移动客户端上时,可能是低效的。当您决定使用外部库,您可能需要优化该库为移动设备。

避免Bitmap浪费

Bitmap是内存消耗的大头,当使用时要及时回收。另外配置:

inSampleSize:缩放比例,图片按需加载,避免不必要的大图载入。

decode format:解码格式,选择ARGB_8888/RBG_565/ARGB_4444/ALPHA_8,存在很大差异。

Cursor关闭

如查询数据库的操作,使用到Cursor,也要对Cursor对象及时关闭。

监听器的注销

Android程序里面存在很多需要register与unregister的监听器,手动add的listener,需要记得及时remove这个listener。

转载请注明:PHP学习 » Android 内存优化

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址