• APP性能之终端兼容优化分享


    对于种类繁多Android设备适配. 对开发者来说, 也是除了应用逻辑以外需要重点考虑的一个重要因素. 因为这点将会直接影响到用户对应用的印象和体验. Google对此也出了很多应对措施来解决Android的碎片化.
    我也来分享下我平时遇到的性能之终端兼容优化的办法:
    1, 多屏幕, 多分辨率
    ①这点也许这是开发者遇到的最头疼的问题, 甚至导致某些开发者中途放弃Android, 转投其他平台. 其实这点并不可怕, Google为我们提供了很多resource qualifier来解决此问题. 根据不同分辨率, 不同系统版本, 不同屏幕尺寸, 不同屏幕方向, 不同语言, 不同地区, 甚至不同UI的模式, 不同的sim卡也能匹配, 具体请看下表: (附链接http://developer.android.com/guide/topics/resources/providing-resources.html)
    6.png
    ②尽量使用Android提供的各种Drawable来绘制(BitmapDrawable, NinePatchDrawable, ShapeDrawable等等都是对适配很有用的), 详情见网址: http://developer.android.com/guide/topics/resources/drawable-resource.html
    如下代码:

    <?xml version="1.0" encoding="utf-8"?>

    <shape xmlns:android="http://schemas.android.com/apk/res/android" >

        <gradient

            android:angle="90"

            android:endColor="#ff5f9dde"

            android:startColor="#ff3972bf" >

        </gradient>

    </shape>

    效果如下:
    12.png
    ③尽量准备多套UI资源图, 针对不同分辨率的屏幕. drawable-ldpi, drawable-mdpi, drawable-hdpi是最常见的分辨率的. 别让mdpi的设备用hdpi的资源, 这样会造成消耗大量的内存, 一般mdpi的设备都硬件配置都不高.
    ④当layout里面用到LinearLayout时, 子View用android:layout_weight来自动排布, 也是一个用作自适应不错的选择. 就如下面代码:

    <?xml version="1.0" encoding="utf-8"?>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

        android:layout_width="fill_parent"

        android:layout_height="fill_parent" >

        <Button

            android:layout_width="0dp"

            android:layout_height="wrap_content"

            android:layout_weight="1" />

        <Button

            android:layout_width="0dp"

            android:layout_height="wrap_content"

            android:layout_weight="1" />

        <Button

            android:layout_width="0dp"

            android:layout_height="wrap_content"

            android:layout_weight="1" />

        <Button

            android:layout_width="0dp"

            android:layout_height="wrap_content"

            android:layout_weight="1" />

    </LinearLayout>

    真机上运行效果
    999.png
    屏幕变化
    998.png
    Pad
    997.png
    当LinearLayout的android:orientation为horizontal时别忘了将含layout_weight属性的子View的layout_width设置成0dp. 当为vertical时, 将含layout_weight属性的子View的layout_height设置成0dp, 这样可以减少LinearLayout在onMeasure时计算量.
    2, 多版本
    ①说到版本兼容性, 第一个想到的就要是用低版本sdk开发, 这样在所有高于设备上正常运行. 但是有个弊端就是无法使用Android高版本提供新特性.
    于是这个时候"Android Compatibility package"就出场了, 这个library是Google为低版本提供一些兼容高版本的特性, 如Fragment, ViewPager等等, 开发者可以在低版本的系统使用高版本的特性.
    但是如果需要同时兼容高低版本. 就需要用到android:targetSdkVersion和android:minSdkVersion, android:minSdkVersion很好理解, 就是该应用支持的最低api level的设备, android:targetSdkVersion则是用来区分是使用"Android Compatibility package"提供的兼容特性还是使用系统本身提供的.

    <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="11" />

    比如上面的代码, 就是最低版本是api level是7(Android 2.1), 当api level低于11(Android 3.0)就使用"Android Compatibility package"提供的兼容类(Fragment), 高于11(Android 3.0)就使用3.0提供的.
    同时编译的时候需要把eclipse的project build target设置成api level高于11的
    ②还有个版本兼容性能用到的就是Java提供的反射机制, 这样也可以使开发者的应用在某个方法可用的时候进行调用. 这个可以通过查询开发文档进行查询. 流程看下图:
    屏幕快照 2012-05-15 下午12.56.54.png
    当然针对某些实例变量也能通过反射来改变, 这个就需要去查询源码, 不推荐.
    3, UI优化
    ①layoutopt - 曾经作为独立的app于sdk/tools目录中, 高版本的sdk将他集成到ADT中了. 主要功能检测你编写的layout中哪些View是无用的, 哪些是可以两个合并到一个, 达到相同的UI效果的.
    该工具报出如下警告. 以便于开发者修改. 具体大家可以Google下这个工具的用法.
    11:17 This LinearLayout layout or its LinearLayout parent is useless
    5:22 The root-level <FrameLayout/> can be replaced with <merge/> 10:21 This LinearLayout layout or its FrameLayout parent is useless
    -1:-1 This layout has too many views: 83 views, it should have <= 80!
    现在该工具已经集成到ADT了, 编写代码的同时就会显示出警告.
    opt.png
    ②hierarchyviewer - 该工具位于sdk/tools目录中. 可以帮助开发查看自己应用View的结构和嵌套的层次, 嵌套层次太多也会对性能有影响.
    屏幕快照 2012-05-15 下午1.52.22.png
    整个工具基本就是呈现你的应用所使用到的View, 已经层级关系. 开发者可以通过点击节点来获取此节点的当前状态图, 同时节点下会有三个可能是红黄绿的圆点, 分别表示你的这个View在measure, layout, draw所消耗的时间和其他50%的View作对比. 就如生活中的红黄绿灯一样的效果. 绿色当然最好.
    4. 代码优化
    ①说到代码优化, 这儿是我收集的一个表格:

    行为

    时间

    加入一个本地变量                                                                1

    加入一个成员变量                                                               4

    调用String.length()                                                            5

    调用空的静态本地方法                                                        5

    调用空的静态方法                                                                12

    调用空的虚方法                                                                   12.5

    调用空的接口方法                                                               15

    调用HashMap的Iterator:next()方法                               165

    调用HashMap 的put() 方法                                              600

    从XML展开一个视图                                                          22,000

    展开一个包含1个TextView的LinearLayout                    25,000

    展开一个包含6个View的LinearLayout                            100,000

    展开一个包含6个TextView的LinearLayout                   135,000

    运行一个空的 activity                                                       3,000,000

    根据表格, 就知道应该避免做哪些不必要的操作了.
    ②在Android源码中也经常见到这样的写法, "将一个实例变量赋值给一个局部变量, 然后用这个局部变量"(局部缓存), 特别是在onDraw方法或者循环中. 会经常用到. 因为Java访问局部变量速度会比访问实例变量快. 这是一个用空间换时间的操作.
    ③尽量使用普通循环, 而不是使用使用实现Iterable接口的for each循环. 因为移动设备性能有限. Iterable循环会重复调用Iterator的hasNext()和next()方法, 从上面表格可以看出调用方法, 比访问属性更耗时.

  • 相关阅读:
    AUSU 安装Win10注意事项
    华硕笔记本无法设置U盘启动,快捷启动不能识别
    postgres 得到所有表空间 和 表空间的位置
    python 远程链接、搜索与下载
    python 读取 postgreSQL 数据保存CSV文件
    weka 初练之 文本分类
    基于springMVC+mybatis的实践记录
    简单的springMVC + mybatis 编写程序流程
    sql查询 生成列号
    通过资源文件 验证拦截机制
  • 原文地址:https://www.cnblogs.com/jqyp/p/2524296.html
Copyright © 2020-2023  润新知