Android性能优化

在上一篇中介绍了性能优化的概念、内存泄漏和性能优化方式

Android性能优化(上)

我们继续说说Android性能优化

数据库性能优化

索引

简单的说,索引就像书本的目录,目录可以快速找到所在页数,数据库中索引可以帮助快速找到数据,而不用全表扫描,合适的索引可以大大提高数据库查询的效率。

(1). 优点

大大加快了数据库检索的速度,包括对单表查询、连表查询、分组查询、排序查询。经常是一到两个数量级的性能提升,且随着数据数量级增长。

(2). 缺点

索引的创建和维护存在消耗,索引会占用物理空间,且随着数据量的增加而增加。在对数据库进行增删改时需要维护索引,所以会对增删改的性能存在影响。

使用场景

A.当某字段数据更新频率较低,查询频率较高,经常有范围查询(>, =, <=)或order by、group by发生时建议使用索引。并且选择度越大,建索引越有优势,这里选择度指一个字段中唯一值的数量/总的数量。

B. 经常同时存取多列,且每列都含有重复值可考虑建立复合索引

索引分类

直接创建索引和间接创建索引

直接创建: 使用sql语句创建,Android中可以在SQLiteOpenHelper的onCreate或是onUpgrade中直接excuSql创建语句,语句如

CREATE INDEX mycolumn_index ON mytable (myclumn)

间接创建: 定义主键约束或者唯一性键约束,可以间接创建索引,主键默认为唯一索引。

普通索引和唯一性索引

普通索引:CREATE INDEX mycolumn_index ON mytable (myclumn)

唯一性索引:保证在索引列中的全部数据是唯一的,对聚簇索引和非聚簇索引都可以使用,语句为CREATE UNIQUE COUSTERED INDEX myclumn_cindex ON mytable(mycolumn)

单个索引和复合索引

单个索引:索引建立语句中仅包含单个字段,如上面的普通索引和唯一性索引创建示例。

复合索引:又叫组合索引,在索引建立语句中同时包含多个字段,语句如:CREATE INDEX name_index ON username(firstname, lastname),其中firstname为前导列。

聚簇索引和非聚簇索引(聚集索引,群集索引)

聚簇索引:物理索引,与基表的物理顺序相同,数据值的顺序总是按照顺序排列,语句为:CREATE CLUSTERED INDEX mycolumn_cindex ON mytable(mycolumn) WITH ALLOW_DUP_ROW,其中WITH ALLOW_DUP_ROW表示允许有重复记录的聚簇索引

非聚簇索引:CREATE UNCLUSTERED INDEX mycolumn_cindex ON mytable(mycolumn)

索引默认为非聚簇索引

使用规则

对于复合索引,把使用最频繁的列做为前导列(索引中第一个字段)。如果查询时前导列不在查询条件中则该复合索引不会被使用。

如create unique index PK_GRADE_CLASS on student (grade, class)

select * from student where class = 2未使用到索引

select * from dept where grade = 3使用到了索引

避免对索引列进行计算,对where子句列的任何计算如果不能被编译优化,都会导致查询时索引失效

select * from student where tochar(grade)=’2′

比较值避免使用NULL

多表查询时要注意是选择合适的表做为内表。连接条件要充份考虑带有索引的表、行数多的表,内外表的选择可由公式:外层表中的匹配行数

内层表中每一次查找的次数确定,乘积最小为最佳方案。实际多表操作在被实际执行前,查询优化器会根据连接条件,列出几组可能的连接方案并从中找出系统开销最小的最佳方案。

查询列与索引列次序一致

用多表连接代替EXISTS子句

把过滤记录数最多的条件放在最前面

善于使用存储过程,它使sql变得更加灵活和高效(Sqlite不支持存储过程::>_<::>

事务

使用事务的两大好处是原子提交和更优性能。

原子提交

原子提交意味着同一事务内的所有修改要么都完成要么都不做,如果某个修改失败,会自动回滚使得所有修改不生效。

更优性能

Sqlite默认会为每个插入、更新操作创建一个事务,并且在每次插入、更新后立即提交。

这样如果连续插入100次数据实际是创建事务->执行语句->提交这个过程被重复执行了100次。如果我们显式的创建事务->执行100条语句->提交会使得这个创建事务和提交这个过程只做一次,通过这种一次性事务可以使得性能大幅提升。尤其当数据库位于sd卡时,时间上能节省两个数量级左右。

Sqlte显示使用事务,示例代码如下:

public void insertWithOneTransaction() {

SQLiteDatabase db = sqliteOpenHelper.getWritableDatabase();

//开始一个事务

db.beginTransaction();

try {

for (int i = 0; i < 100; i++) {

db.insert(yourTableName, null, value);

}

// 设置当前事务成功

db.setTransactionSuccessful();

} catch (Exception e) {

e.printStackTrace();

} finally {

//结束事务

db.endTransaction();

}

}

其中sqliteOpenHelper.getWritableDatabase()表示得到写表权限。

其他Sqlite的优化

语句的拼接使用StringBuilder代替String

简单的String相加会导致创建多个临时对象消耗性能。StringBuilder的空间预分配性能好得多。如果你对字符串的长度有大致了解,如100字符左右,可以直接new StringBuilder(128)指定初始大小,减少空间不够时的再次分配。

查询时返回更少的结果集及更少的字段。

查询时只取需要的字段和结果集,更多的结果集会消耗更多的时间及内存,更多的字段会导致更多的内存消耗。

少用cursor.getColumnIndex

根据性能调优过程中的观察cursor.getColumnIndex的时间消耗跟cursor.getInt(索引号)相差无几。可以在建表的时候用static变量记住某列的index,直接调用相应index而不是每次查询。

public static final String HTTP_RESPONSE_TABLE_ID = _ID;

public static final String HTTP_RESPONSE_TABLE_RESPONSE = "response";

public List getData() {

……

cursor.getString(cursor.getColumnIndex(HTTP_RESPONSE_TABLE_RESPONSE));

……

}

//优化为

public static final String HTTP_RESPONSE_TABLE_ID = _ID;

public static final String HTTP_RESPONSE_TABLE_RESPONSE = "response";

public static final int HTTP_RESPONSE_TABLE_ID_INDEX = 0;

public static final int HTTP_RESPONSE_TABLE_URL_INDEX = 1;

public List getData() {

……

cursor.getString(HTTP_RESPONSE_TABLE_RESPONSE_INDEX);

……

}

异步线程

Sqlite是常用于嵌入式开发中的关系型数据库,完全开源。与Web常用的数据库Mysql、Oracle db、sql server不同,Sqlite是一个内嵌式的数据库,数据库服务器就在你的程序中,无需网络配置和管理,数据库服务器端和客户端运行在同一进程内,减少了网络访问的消耗,简化了数据库管理。不过Sqlite在并发、数据库大小、网络方面存在局限性,并且为表级锁,所以也没必要多线程操作。

Android中数据不多时表查询可能耗时不多,不会导致ANR,不过大于100ms时同样会让用户感觉到延时和卡顿,可以放在线程中运行,但Sqlite在并发方面存在局限,多线程控制较麻烦,这时候可使用单线程池,在任务中执行db操作,通过Handler返回结果和UI线程交互,既不会影响UI线程,同时也能防止并发带来的异常。

可使用Android提供的AsyncQueryHandler或类似如下代码完成:

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

singleThreadExecutor.execute(new Runnable() {

@Override

public void run() {

db.insert("你的表名", null, value);

handler.sendEmptyMessage(xx);

}

});

移动网络优化

一个网络请求可以简单分为连接服务器 -> 获取数据两个部分。

其中连接服务器前还包括DNS解析的过程;获取数据后可能会对数据进行缓存。

连接服务器优化策略

不用域名,用IP直连

省去 DNS 解析过程,DNS 全名 Domain Name System,解析意指根据域名得到其对应的 IP 地址。

如:http://www.codekk.com 的域名解析结果就是104.236.147.76。

首次域名解析一般需要几百毫秒,可通过直接向IP而非域名请求,节省掉这部分时间,同时可以预防域名劫持等带来的风险。

当然为了安全和扩展考虑,这个IP可能是一个动态更新的IP列表,并在IP不可用情况下通过域名访问。

服务器合理部署

配合上面说到的动态 IP 列表,支持优先级,每次根据地域、网络类型等选择最优的服务器IP进行连接。

对于服务器端还可以调优服务器的TCP拥塞窗口大小、重传超时时间(RTO)、最大传输单元(MTU)等。

获取数据优化策略

连接复用

节省连接建立时间,如开启keep-alive

Http 1.1 默认启动了keep-alive。对于Android来说默认情况下HttpURLConnection 和HttpClient都开启了keep-alive。

其他网络请求框架也可以进行相应配置

请求合并

即将多个请求合并为一个进行请求,比较常见的就是网页中的CSS Image Sprites。 如果某个页面内请求过多,也可以考虑做一定的请求合并。

减小请求数据大小

对于 POST 请求,Body 可以做 Gzip 压缩,如日志。

对请求头进行压缩

这个http 1.1不支持,spdy及http 2.0支持。http 1.1 可以通过服务端对前一个请求的请求头进行缓存,后面相同请求头用md5之类的id来表示即可。

CDN缓存静态资源

缓存常见的图片、JS、CSS 等静态资源。

减小返回数据大小

压缩

一般API数据使用Gzip压缩

精简数据格式

如JSON代替 XML,WebP代替其他图片格式

对于不同的设备不同网络返回不同的内容 如不同分辨率图片大小。

增量更新

需要数据更新时,可考虑增量更新。如常见的服务端进行bsdiff,客户端进行 bspatch。

大文件下载

支持断点续传,并缓存Http Resonse的ETag标识,下次请求时带上,从而确定是否数据改变过,未改变则直接返回304。

数据缓存

缓存获取到的数据,在一定的有效时间内再次请求可以直接从缓存读取数据。

现在的网络请求框架都可进行相应的缓存配置

今天周末,就说这么多(懒),祝大家周末Happy

android服务器 性能,Android性能优化(中)相关推荐

  1. android 服务器sessionid,Android用WebView获取sessionid保持登录状态

    我们需要和web服务器保持登录状态.所以我们需要记录sessionid: 我们将网页用webview加载之后,用CookieManager 来获取本地的cookies .然后设置到webview里面去 ...

  2. android服务器app,Android APP中使用NanoHTTPD搭建轻量级服务器

    最近接到一个需求,由后台主动给APP发送消息,且对实时性的要求较高. 经过探索评估,发现NanoHTTPD很适合,非常轻便. 本文主要内容如下: 1.依赖导入: 2.设置IP和端口: 3.启动服务和后 ...

  3. Android服务器django,Android发送发送请求到django服务器csrf失败

    我想我的 Android应用程序能够发送一些信息到我的django服务器.所以我做的Android应用程序发送一个发布请求到mysite /上传页面,django的这个页面的视图将基于post数据工作 ...

  4. android服务器接口测试,Android单元测试:网络接口测试

    在平日的开发中,我们用后台写好给我们接口去获取数据.虽然我们有一些请求接口的工具,可以快速的拿到返回数据.但是在一些异常情况的处理上就不太方便了.我列出以下几个痛点: 快速的查看返回数据与数据的处理. ...

  5. android 服务器201,Android端i-jetty服务器开发(八)

    http://blog.csdn.net/kongxx/article/details/7237034 Jetty实战之 嵌入式Jetty运行web app 1. 运行标准的war文件 1.1 首先找 ...

  6. Android 进阶第二篇——性能优化

    Android 进阶第二篇--性能优化 一些Android书籍喜欢把性能优化放在最后的章节,简单提一提作为内容全面的点缀.在这里我将工具使用和性能优化的一些个人经验放在进阶系列博客的开始,因为我认为防 ...

  7. android系统功耗优化(2)---Android最佳实践之性能 - 电池续航时间优化

    Android最佳实践之性能 - 电池续航时间优化 Doze和App Standby的优化(API23) 参考地址:http://developer.android.com/training/moni ...

  8. 关于android性能,内存优化 http://www.cnblogs.com/zyw-205520/archive/2013/02/17/2914190.html

     随着技术的发展,智能手机硬件配置越来越高,可是它和现在的PC相比,其运算能力,续航能力,存储空间等都还是受到很大的限制,同时用户对手机的体验要  求远远高于PC的桌面应用程序.以上理由,足以需要 ...

  9. Android之——性能与内存优化

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/46987951 写出高效代码的两条基本的原则:(1)不要做不必要的事:(2)不要分配 ...

最新文章

  1. 2019年——欢度中秋,喜迎国庆
  2. 如何在已安装TMG2010服务器上安装Symantec Backup Exec 2010 Remote Agent
  3. java中解密技术是什么_详解Java 加密解密技术的分类和归纳
  4. php form action跳转,form表单页面跳转方式提交练习
  5. hadoop程序MapReduce之DataSort
  6. 列表与元组——Python基础语法
  7. MVC之使用Nhibernate
  8. 动画演绎Java常用数据结构
  9. ArduinoUNO实战-第九章-光敏电阻或亮度传感器
  10. API LayoutInflater
  11. “天池”淘宝用户消费行为分析——sql
  12. 反向延长线段什么意思_反向延长线是什么意思
  13. 【Junit Experiment】Junit 软件质量测试实验--日期格式规范性+字符串格式规范性
  14. Busiest Computing Nodes
  15. 显示行数 设置ssh终端_SSH终端命令工具:zoc7 for Mac
  16. 离散数学实验报告四——图的应用
  17. Windows 批量打印
  18. uni-app三级联动笔记
  19. matlab 函数 平移,MATLAB图线先下平移
  20. upper_bound 和 lowwer_bound 用法

热门文章

  1. quartz java 线程 不释放_java Quartz 内存泄漏
  2. python自动化运维快速入门pdf下载_Python自动化运维快速入门
  3. 【渝粤题库】广东开放大学 英语语音与听说 形成性考核
  4. 【渝粤题库】国家开放大学2021春1359高级英语写作题目
  5. spss三次指数平滑_17 统计学:SPSS基础
  6. 杀java_java怎么杀掉java进程
  7. 【自适应盲均衡4】基于RLS的多径衰落信道均衡算法(RLS-CMA)的理论推导与MATLAB仿真
  8. MADDPG中环境怎么配置,multiagent包解决
  9. qt linux 添加库文件路径,linux下qt使用第三方库的那些事
  10. 主板螺丝是机箱配还是主板配_要配新电脑,A520主板和B450主板哪一个更加值得购买?...