Android小知识——关于Android内存、性能优化的一些细节

转载 2016年05月30日 11:43:42

1、使用优化过的数据容器。

       在Android framework下,建议使用优化过的数据容器比如:SparseArray,SparseBooleanArray,LongSparseArray。通用的HashMap实现的内存使用率非常的低,因为他需要为每一个mapping创建一个分离的entry object。另外,SparseArray类避免了系统对有些key的自动装箱,因而带来了更高的效率。 

2、注意内存的开销。 

     注意你使用的语言和第三方库的成本和开销,要自始至终的将这些因素考虑在你的程序设计中。通常,有些事情表面上看着没什么问题但实际上的开销让人惊叹。比如: 
   ·枚举相对于静态常量来说,需要两倍甚至更多的内存。你应该完全避免在Android中使用枚举。 
    ·每一个在java中的类(包括匿名内部类)使用大约500 bytes的代码量。
   ·每一个类的实例拥有12-16 bytes的RAM消耗。
   ·放置一个单独的实体到HashMap中,一个额外加的实体对象分配需要花费32 bytes。
 

3、关于代码的抽象 

    抽象是一个好的编程的基础,因为抽象可以提高代码的灵活性和可维护性。然而抽象也带来了一定的花销,一般情况下,他们有更多的代码需要执行,需要更多的时间和更多RAM来将这些代码映射到内存中。因此,如果你的抽象不能带来巨大的好处,你就应该割掉你的赘肉。

4、避免依赖注入框架 

    虽然注入框架给我们带来了很多方便,但是在使用这些框架的时候,框架需要花费很多时间来扫描我们自己写的代码,甚至会将哪些你根本不需要的东西也加载到内存中。

5、小心的使用扩展库 

    很多扩展库的代码不是针对手机环境开发的,可能在用到移动客户端的时候会导致很低的效率。因此在使用之前,需要评估一下其占用内存的大小。
    即使库针对手机开发,也会有潜在的危险,因为每一个Library做的事情不尽相同。比如,一个Library使用nano protobufs而另一个使用micro protobufs。现在,在你的app中就有两个protobuf。类似情况经常发生。

6、使用混淆器移除不必要的代码 

    ProGuard工具通过移除无用代码,使用语意模糊来保留类,字段和方法来压缩,优化和混淆代码。可以使你的代码更加完整,更少的RAM 映射页。

7、使用多个进程(注意是process 不是 thread ok?) 

    如果这适合你的app,可能帮助你管理你的app的内存就是将你的app多个部分分配到多个进程中。该技术必须小心使用并且大多数应用不应该运行在多个进程下。这个技术的主要应用是后台工作跟天台工作一样重要的情况下。典型应用就是:当音乐播放器从服务器下载并长时间播放音乐,一般将其分为两个进程:一个是UI,另一个位置后台服务的运行。
like this:

<service android:name=".PlaybackService"          android:process=":background" /> 

process后面需要记住要有个":",这表示该进程属于你的app。
 一般情况下,一块基本的空进程需要的内存大小在1.4m左右。

adb shell dumpsys meminfo com.example.android.apis:empty8、基本性能优化方法的基本原则: 

    1)不要做你不必要的工作;
    2)不要申请不必要的内存;

    例如,你明明知道一个方法返回一个String之后,你需要对这个String重新进行修改,那么就不要返回一个String,返回一个StringBuffer会是你更好的选择。
    再比如,使用int比使用Integer占用更少的空间。这个大家肯定都是晓得的。
    数组比一个Map拥有更好的性能。
    如果你的方法不需要访问类字段,那么让你的方法是static的吧,这将会带来15%-20%速度的提升。
    对于常量,请尽量使用static and final定义。如果使用final定义常量之后,会减少编译器在类生成时初始化<clinit>方法调用时对常量的存储,对于int型常量,将会直接使用其数值来进行替换,而对于String对象将会使用相对廉价的“string constant”指令来替换字段查找表。虽然这个方法并不完全对所有类型都有效,但是,将常量声明为static final绝对是一个好的做法。
    避免Getters/Setters。虽然在一般的面向对象的设计模式中使用Getter和Setter是稀松平常的事情,但是在Android中使用getters/Setters是一个非常糟糕的主意,方法的调用相对于直接查找字段来说十分的昂贵。在没有JIT的情况下,直接对字段进行访问要比通过Getter访问快了近3倍。在有JIT的情况下,前者比后者快近7倍。
    使用最新的循环方式。比如增强for。
    避免使用浮点类型。在某些可以的情况下,将浮点替换成整型数据,然后进行计算会得到更精确的结果和更快的速度。
    小心使用Native Methods。这里需要纠正的是,Native 方法并不一定能提高你应用的速度,有些甚至会拖后腿,因为,首先来说就需要一部分开销在Java-native transition上,而且JIT并不能对其进行优化。另外你需要为每个你想要在其上运行的系统结构上进行编译;即便是同一个处理器上,你也可能需要多个版本,比如为G1上的ARM处理器编译的就不能很好的在Nexus One的ARM上运行。Native代码最主要的用途是,你已经有了很多native 代码,并且你迫切希望接入Android中。而不是使用Native Method来提高你应用中某部分代码的运行速度。
    对于效率的提高除了使用遵守上面两条外基本准则外,选择合适的算法和数据结构也是非常关键的。

 9、关于UI上的一些问题

        Hierarchy Viewer通过他,可以看到你自己的Layout文件存在的问题。你可以看到你的Layout每一部分计算,布局,渲染所需要的时间。尽量的使你的Layout扁平话,深度最好保持 在三层之内。 RelativeLayout是解决使用LinearLayout堆叠多层问题的利剑。那些为了方便 使用LinearLayout的layout_weight属性的哥们,需要重点注意,这个属性真的可以减慢measure速度。所以在使用之前,一定要再三考虑,是否真的不能通过其他方法来完成你要的效果? 
    官方文档上 推荐使用RelativeLayout和GridLayout来避免Layout深度过深的问题。 
    之前看文档,Google提供一个叫 ViewSub的控件来优化那些不是必须要立即在UI上显示的控件,感兴趣的同学可以去看看。在API Level 1中就提供了这个东西,但是在实际开发中很少见到有人用或者提及(可能是我孤陋寡闻,公司就两个Android开发,另一个还要转IOS,我们俩的Android技术就代表了我们公司的Android技术能力,想想真悲哀!),其实蛮好用的。 
    重用Layout。可以使用<include/> <merge/>将其他布局嵌入到当前布局中。 
    ListView的优化:ViewHolder的使用;AsyncTask的使用;针对ListView当前滑动状态,对图片数据的加载进行控制;(ListView在配以AsyncTask加载图片时需要注意图片的加载完显示的位置以及图片的缓存问题,具体可以参考Google的 Demo

 10、将大消耗操作交给多个线程。

 11、如果你的应用需要发送Broadcast但是又不希望别的应用获取到,或者你不希望处理别的应用发送的同样的action,那么请使用LocalBroadcastManager

    该类是在Android Support v4中提供的,用来在同一个应用内的不同组件之间发送Broadcast。好处上面说了,可以保证应用的私密性。会比全局广播有更高的效率,但是官方文档没有说明具体数值。具体使用方法:

 LocalBroadcastManager.getInstance(this).registerReceiver( mStateReceiver, mStatusIntentFilter);LocalBroadcastManager.getInstance(this).sendBroadcast(localBroadcastIntent); 

   另外Broadcast的注册一定要放在Activity的有响应的时候注册,一般在onResume()注册,在onPause()的时候取消注册。尽量不要程序走到onDestroy()方法里面才对Broadcast取消注册,因为有些时候不会走到该方法,就会导致崩溃或者再次进入界面是多次注册。

12、关于Fragment使用: 

1)无论在哪里使用getResources()方法,都是需要判断是否获取的为null。

2)在使用Fragment+asyntask时的输出结果中最好使用isAdded()方法来判断一下,如果为真,那么才进行后续操作。

13、关于动画 

动画结束时,不能修改View的层级关系,如果要修改,使用如下方法:

@Override

public void onAnimationEnd(Animation animation) {

    new Handler().post(new Runnable() {

        public void run() {

            myLayout.removeView(mRemoveView);

        }

    });

}

 

android常用的必备基础知识

首先从四大组件说起:  Activity:  生命周期:  activity三种状态:运行(运行在最前端)、停止(不可见,完全被覆盖)、暂停(可见,但前端还有其他activity)  生命周期...
  • qq_25462179
  • qq_25462179
  • 2017年06月30日 17:37
  • 178

[Android 性能优化系列]那些不能忽略的小细节

本文将主要介绍一些能够ti's
  • kifile
  • kifile
  • 2014年11月05日 13:37
  • 1476

Android中高手必须了解的关于View的细节(进阶必备)

关于Android的视图体系,有一些位置、坐标系、定位的小细节可能开发者并没有注意到,本文将指出一些让人惊讶的小细节,并以实例证明。 一、Android的视图组织体系不为人知的小细节 ...
  • a369414641
  • a369414641
  • 2016年11月08日 13:05
  • 375

移动App运营推广的13个细节

安卓渠道运营要关注哪些内容? 1、渠道的玩法和规则 知道每家渠道的玩法、相关规则(活动和首发) 开发者后台帮助文档 渠道排名规则:下载量、评论的权重 2、市场最近动态 渠道的开发者...
  • m13295105247
  • m13295105247
  • 2018年01月29日 14:22
  • 33

SQL Server中的一些知识

如果要在数据库中判断有没有某个表或存储过程,或触发器等等。都可以从数据库中的sysobjects表中查找。比如:要判断数据库pubs中有没有表authors,可以这样查询:        Select...
  • shipfi
  • shipfi
  • 2004年11月26日 11:33
  • 635

经济学小知识

经济学小知识(1) 纳什均衡一农户在杀鸡前的晚上喂鸡,不经意地说:快吃吧,这是你最后一顿! 第二天,见鸡已躺倒并留遗书:爷已吃老鼠药,你们别想吃爷了,爷他妈也不是好惹的。 纳什均衡理论:当对手知道了...
  • wishfly
  • wishfly
  • 2006年07月13日 03:14
  • 1748

垃圾回收的一点小知识

前两天被人问到了一个问题,关于垃圾回收中的闭环的问题,大概问题是 a=b.v; b=c.v; c=a.v; 如果把a干掉那么b和c会不会被回收?? 首先划一下内存图...
  • sunyunlong_1
  • sunyunlong_1
  • 2017年12月10日 23:47
  • 21

关于 微信 小知识

关于微信的知识 1、朋友圈和查找附近的人插件能卸载吗? 朋友圈和查找附近的人可以在设置里卸载 2、查询微信好友数量的办法 通讯录下拉到 最底部,另一个是我 -> 设置->通用->功能->群发...
  • ralbatr
  • ralbatr
  • 2014年01月16日 09:38
  • 5044

关于企业内部系统访问地址的一些思考

  • u013560667
  • u013560667
  • 2014年06月11日 10:33
  • 518

关于plsql的一些知识点

plsql登录时的Database是服务名,这里的服务名是安装oracle客户端和服务端时设置的数据库服务名(如:orcl),并不是设置的全局数据库的名称(如:turing)。而在web项目中jdbc...
  • zbyluxzing
  • zbyluxzing
  • 2015年12月10日 20:56
  • 223
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android小知识——关于Android内存、性能优化的一些细节
举报原因:
原因补充:

(最多只允许输入30个字)