Android性能优化

Android性能优化老生常谈,优化点比较宽泛和复杂,不同类型的项目优化点也不相同。但是可以规划为若干个点,总有一点适合你。

应用层的性能优化通常可以从以下几个方面考虑

1.界面布局优化(merge ,include ,ViewStub,减少布局嵌套层次);

   merge可进行多余嵌套层次的移除处理,include复用同一布局在多个界面中 ,ViewStub可进行隐藏布局的不加载。

2. 采用合理的数据结构和算法提高程序性能,这往往是决定程序性能的关键;

     程序设计上注意内存和CPU运算的性能。 

 3. 合理配置数据库缓存类型和优化SQL语句加快读取速度,使用事务加快写入速度;

     优化sql查询不管是后端还是前端都应该注意的内容,大量数据读取和更新建议开启事务操作,提升性能和速度的效果比较明显。

     同样操作5000条数据。开启事务与不开启事务对比。添加事务处理,把5000条插入作为一个事务

     dataBase.beginTransaction();    //手动设置开始事务

    //数据插入操作循环

dataBase.setTransactionSuccessful();   //设置事务处理成功,不设置会自动回滚不提交//这个之间不可以做事务操作.

dataBase.endTransaction();        //处理完成

db.execSQL("insert into  user values(4,'张三2')");

db.execSQL("insert into  user values(4,'李四2')");

db.execSQL("insert into  user values(4,'王五2')");

db.execSQL("insert into  user values(4,'赵六2')");

db.beginTransaction();// 开启事物

long time1 = System.currentTimeMillis();

try {

db.execSQL("insert into  user values(1,'张三')");

db.execSQL("insert into  user values(2,'李四')");

db.execSQL("insert into  user values(3,'王五')");

db.execSQL("insert into  user values(4,'赵六')");

db.setTransactionSuccessful();

} catch (SQLException e) {

e.printStackTrace();

db.endTransaction();}

db.endTransaction();

long time2 = System.currentTimeMillis();System.out.println("消耗时间:" + (time2 - time1));

消耗时间:4或10等等.

而去掉事务执行结果:

消耗时间:76或128等等.

4. 采用多线程、缓存数据、延迟加载、提前加载等手段优化操作;

凡是操作数据量略大的都应该采用多线程处理,重复数据应该进行缓存,加载数据弹出loading可进行延迟处理。

5. 尽量使用系统方法,提升效率,除非明显发现系统方法缺陷;

系统提供的API方法往往优于自定义方法,使用上也多数更加简便。比如:

系统提供的字符串比较方法TextUtils.equals()已经考虑到了字符串为null的情况,不会由于前置字符串为null造成崩溃。同理:TextUtils.isEmpty()方法、ArrayList.subList()方法。感兴趣的可以研究一下系统提供的工具方法。性能上比我们自己写的方法要好很多。

6. 合理释放资源(流的关闭,cursor,bitmap等).

如图所示的数据库查询操作中表面上看来没有什么问题,但是循环查询了若干次,每次采用一个cursor对象,但是实质上是一个cursor对象指向不同的地址,由于每次查询都是返回新的cursor对象,最后只关闭了一个cursor对象,所以会在造成许多cursor对象的未关闭,耗费性能。所以在操作数据库的时候尽量用一次cursor就跟着关闭一次cursor。对于流的操作也是如此。在一些流资源、数据库操作资源和一些耗内存的资源上,比如流、cursor、bitmap。这些资源的使用上需要多注意。使用之后及时释放。如果是频繁使用的场景下可能频繁申请和释放也比较耗费资源,可以考虑用资源池等手段处理。

7.使用工具分析性能问题,找出性能瓶颈;  

写出高效的代码需要遵循两条原则:1,不执行不必要的操作; 2,不分配不必要的内存

一个程序员的代码约束

1.避免创建不必要的对象

每创建一个对象系统就会在堆内存申请一块儿空间。大量申请内存会造成OOM。如果对于一个操作可以用一个对象完成尽量不要申请多余的对象,即便对象不再使用的时候虚拟机会进行回收,但也造成了资源的多于占用。

2. 合理使用static成员

staitc成员的特殊性能简化许多操作,但是使用上千万注意内存泄露的问题。

最经典的内存泄漏情况就是Static成员引用Activity。

   public class MainActivity extends Activity{  

    public static Context mContext;  

    @Override  

    protected void onCreate(Bundle savedInstanceState) {  

        super.onCreate(savedInstanceState);  

        setContentView(R.layout.activity_main);  

        mContext = this;  

    }  

public class MainActivity extends Activity{  

    public static Context mContext;  

    @Override  

    protected void onCreate(Bundle savedInstanceState) {  

        super.onCreate(savedInstanceState);  

        setContentView(R.layout.activity_main);  

        mContext = this;  

    }  

在这种情况下Context对象为静态的,那么Activity就无法正常的销毁,常驻内存,造成内存泄漏。


3. 使用增强for循环 (除了ArrayList)

4.使用package代替private以便私有内部类高效访问外部类成员

5.合理使用浮点类型(在Android设备中浮点型大概比整型数据处理速度慢两倍,所以如果整型可以解决的问题就不要用浮点型)

计算机在处理数据上是没有除法的这个定义的,除法操作都是一律转换为乘法进行处理,所以在计算的时候将/2这样的操作转化为*0.5这样的写法效率更高。

6,合理使用位运算替换乘除法数据在计算机中都是2进制存储,也就是010101的方式存储,这样2的整数倍的乘除法操作就可以通过位运算移位进行处理,这种方式是速度最快的,效率最高。

如图所示:同样处理1000条数据,将每一个数除以2,除法方式用了254毫秒,乘法用了88毫秒,位运算用了51毫秒。

7.采用优化布局层数, 采用

8.延时加载View. 采用ViewStub 避免一些不经常的视图长期被引用,占用内存.

9.移除无用背景,避免同一区域多次重绘,例如移除Activity默认背景,提升activity加载速度。

10.流相关资源,cursor 使用完毕及时关闭。  

11.BroadCast动态注册时,记得要在调用者生命周期结束时unregisterReceiver,防止内存泄漏

12.针对ListView的性能优化,或者采用RecyclerView,类似思想复用思想也能应用到项目中

13.合理使用StringBuffer,StringBuilder,String

14.尽量使用局部变量

局部变量在应用上速度会比全局变量要快很多。

如图:同样操作1000次的循环全局变量7毫秒,局部变量3毫秒。

15. Context的使用注意点(尽量使用application这个变量值) 

尽量使用Application的Context替代Activity的Context

16. 集合中的无用数据及时清除

集合中的数据占用的是堆内存,如果无用数据的集合还存在引用系统是无法回收的,所以无用的集合内数据要及时清除掉,释放资源。

17.较大bitmap压缩后使用,使用完成在合适的时候回收,采用三方框架显示图片

18.尽量不要使用整张的大图作为背景,采用.9图片充当背景

19.了解使用库函数和系统自带函数

20.再Activity和Fragment中使用webview,及得将其置空

以上知识点总结如下:

布局优化尽量不存在冗余嵌套及过于复杂布局,尽量使用GONE替换INVISIBLE,使用weight后尽量将width和heigh设置为0dp减少运算,Item存在非常复杂的嵌套时考虑使用自定义View来取代,减少measure与layout次数等。列表及Adapter优化;尽量复用getView方法中的相关View,不重复获取实例导致卡顿,列表尽量在滑动过程中不进行UI元素刷新等。背景和图片等内存分配优化;尽量减少不必要的背景设置,图片尽量压缩处理显示,尽量避免频繁内存抖动等问题出现。自定义View等绘图与布局优化;尽量避免在draw、measure、layout中做过于耗时及耗内存操作,尤其是draw方法中,尽量减少draw、measure、layout等执行次数。

性能检测工具

从应用上和开发上注意细节尽量提升应用的性能。但是有的时候没有注意到而造成了应用的性能出现问题,比如卡顿、占内存比较高。这时候直接从代码上查找问题不太方便。这时候就需要性能分析工具帮助我们来完成。主要说几种常见的性能分析工具,包括一些简单的使用,和性能分析结果图的查看。

1.Hierarchyviewer.bat检测View的冗余程度,复杂程度,渲染时间。

Hierarchyviewer.bat在最新的AS版本上不支持真机调试,所以可用性不是太高。这个工具主要是来进行ViewTree层级的分析,可以查看View的嵌套层级,直观的看出有没有多余的嵌套。

这张图片摘自于网上,从图中可以看出一个界面的View嵌套等级,如果同一个方向节点由多余的嵌套,可以直观的看出来。

2. Lint布局和资源文件优化工具

Lint布局和资源分析工具主要检测项目中的无用资源 和引用。包括布局文件中的常量字符串。如果这种字符串没有采用@stirng方式引用的话都会被找出来。Google是不建议这种硬编码的。

3. TraceView性能分析优化

TraceView是AndoridStudio自带的性能分析工具,可以分析出你指定操作流程的花费时间,每个函数的调用次数,CPU占用时间等等。真机运行App,打开DDMS。如图所示:

从下图中可以看出每一个函数调用占用此流程CPU的百分比,占用的真实时间,调用次数,重复调用次数等。

拿diapatchMessage方法来说,如图所示:此方法占用了62.5%的CPU时间,真实花费时间1638.315毫秒,调用次数19次。所以如果开发中的某一个界面调用比较卡顿的情况就可以来进行分析一下,看看占用时间比较多的操作是什么。该怎么进行优化,减少调用时间,减少调用次数。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容