Android应用优化_0.1版本

我们首先来看一个普通的Android Studio项目结构:
项目结构
由图所示,我们开始由下往上说吧

第三方包
  1. 很多开源的library不是为移动网络环境编写,如果要集成,应该注意这点。同时了解是否应该去做针对移动环境下的迁移
  2. 不要为了简单的一两个功能而引入一个大而全的library,如果没有适合的library,可以考虑自己去实现
  3. 不要使用一些依赖注入框架(类似Guice或RoboGuice),的确是帮忙省了一些代码,但这些框架在初始化时候就把你的代码扫描进内存,而且这些mapping的内存会一直占用着
build.grade
  1. build.grade中可以开启Proguard功能,Proguard除了混淆代码外,还能做压缩,剔除一些不需要的代码
AndroidManifest.xml
  1. application标签下,有个android:largeHeap属性,可以把它设置为true,这样可以通过getLargeMemoryClass()来获取到一个更大的heap size。但不同的设备会有不同的限制,应该使用getMemoryClass()获取真正实际大小
  2. 设置组件多进程使用,在组件声明中添加属性android:process=":background"即可运行于另一进程,但只有app需要在后台运行与前台一样的大量的任务的时候才合适使用(如音乐播放器)。使用不当会增加内存,而非减少
图片优化
  1. 当bitmap比设备分辨率大时,做适当的压缩
  2. 以其他色彩模式读取bitmap,如ARGB_4444(ALPHA_8/RGB_565/),不过KITKAT之后,使用这个模式系统会自动使用ARGB_8888去读取,详见Bitmap.Config枚举中对此模式的解释
  3. bitmap.recycle()在Android 3.0之后就不必主动调用了,图片像素存储已经放到heap中,会自动回收
  4. 设置Options.inPurgeableinInputShareable:让系统能及时回收内存
  5. 设置图片Cache
  6. 使用WebP格式的图片
布局优化
  1. 善用Hierarchy View、Lint工具
  2. 如果层级关系较深,考虑使用RelativeLayout代替LinearLayout,但只有同样层级时,效率由高到低排序
    FrameLayout > LinearLayout > RelativeLayout
    总之尽量减少布局的层级
  3. 用一个compound drawable 替代一个包含 ImageView 和 TextView 的 LinearLayout 会更有效率
  4. 使用merge/include/ViewStub标签,特别是ViewStub做懒加载
  5. ViewStub 的一个缺陷是,它目前不支持使用 merge标签的 Layout
  6. 避免overdraw,可以在开发者选项中debug GPU overdraw信息
代码优化(首要考虑的是选择合适的算法与数据结构)
  1. 协议Protocol buffers
  2. 注意代码”抽象”,”抽象”会导致更多的代码被加载到内存中,所以如果”抽象”没有为你的应用提供灵活性、可扩展性,就不要使用它了
  3. 使用SparseArray, SparseBooleanArray, 与 LongSparseArray这些优化过的容器,他们避免了对key与value的autobox自动装箱,并且避免了装箱后的解箱。相比之下HashMap更消耗内存
  4. 使用IntentService替代Service,避免service完成任务之后因为停止service失败而引起的内存泄漏
  5. 使用StringBuffer替换String做字符串拼接
  6. 需要取出子字符串时,使用substring方法。这个子串对象是和原string共享内部char[]空间
  7. 把多维的数据分解成一维的数组
  8. 不需要访问一个对象的值时,请保证这个方法是static类型的
  9. 常量声明为Static Final,因为final声明的常量进入了静态dex文件的域初始化部分,而非final的静态变量则放到class常量表中
  10. 类内部直接访问变量,避免内部的Getters/Setters,但如果使用了ProGuard,则ProGuard可以帮助做inline,两者的差异就比较小
  11. 对于ArrayList的遍历使用ArrayList.get(index),但对于其他实现了Iterable 接口集合,使用增强for循环(for(A a : Array))
  12. 避免使用float类型,它的存取速度是int类型的一半
  13. 谨慎使用Native函数。Native 代码是在你已经有本地代码,想把它移植到Android平台时有优势,而不是为了优化已有的Android Java代码使用
  14. 在没有JIT的设备上,使用一种确切的数据类型确实要比抽象的数据类型速度要更有效率,比如调用HashMap map要比调用Map map效率更高,但在有JIT之后效率没有太大差异
  15. 注意枚举,Enums的内存消耗通常是static constants的2倍
  16. 内部类访问外部类时,外部类对象使用package访问权限而非private权限。因为private权限时,内部类会在编译时生成静态方法,而通过方法访问变量总是比直接访问慢
  17. Traceview/dmtracedump,使用traceView测量的数据是未经过JIT优化的,实际运行效果比测量值要好一些
  18. systrace
其他:
  • ANR
    1. 什么时候会穿ANR
      1.1. 对输入事件(例如硬件点击或者屏幕触摸事件),5秒内都无响应
      1.2. BroadReceiver不能够在10秒内结束接收到任务
    2. 解决办法
      2.1. 使用worker线程做耗时任务(AsyncTask/IntentService/ThreadPool/Thread/Runnable/HandlerThread),注意(Runnable/Thread)调用Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);设置线程优先级,以减少创建的新线程和和UI线程之间的资源竞争
      2.2. 从3.0开始,AsyncTask可以通过方法executeOnExecutor运行在自定义的线程池中
      2.3. 线程池中Thread.interrupt()只能停止那些处于等待状态的线程,却不能中断那些占据CPU或者耗时的连接网络的任务。为了避免拖慢系统速度或造成系统死锁,在尝试执行耗时操作之前,应该测试当前是否存在处于挂起状态的中断请求,即
  if (Thread.interrupted()) {
    return;
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值