Android性能优化(第二章)

这章就当填坑了,姑且也算是性能优化吧

⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄

0x00 集合处理

对一些list和数组的操作其实Java已经帮我们做了不少功课了,回想起来在一些使用场景中笔者还傻乎乎的写一堆for each (滑稽),这里就当提个醒。

场景一:

List和数组的转换,这个看官应该都很了解了,这里还是贴出来做下记录。
数组 → List Arrays.asList()传入可变参数类型。例如

//一般写法
List<String> strList=Arrays.asList("1","2");
List<String> strList=Arrays.asList(new String[]{"1","2"});

值得一提的是这里有个隐藏的坑,上述写法是错误的,再用这个List的时候调用add,remove这些method时出现Java.lang.UnsupportedOperationException异常。这是由于Arrays.asList() 返回java.util.Arrays ArrayListArrayListArrays ArrayList和ArrayList都是继承AbstractList,remove,add等method在AbstractList中是默认throw UnsupportedOperationException而且不作任何操作。ArrayList override这些method来对list进行操作,但是Arrays$ArrayList没有override remove(),add()等,所以会throw UnsupportedOperationException。

//正确写法
List<String> strList=new ArrayList<String>(Arrays.asList("1","2"));
List<String> strList=new ArrayList<String>(Arrays.asList(new String[]{"1","2"}));

场景二:

要快速填充默认数据的数组:

 Arrays.fill();

例如

String strs=new String[10];
Arrays.fill(strs,"haha");

这样就能将tests的数组中都填充haha这个字段,这个方法还支持起始位置和末了位置。
List同理Collections.fill()

场景三:

数组的排序看官也应该很熟悉了,值得一提的是,对数组进行Object排序时

Arrays.sort(Object[] objects,Comparator comparator)

一般是写个匿名实现类来完成排序,也可以重新在Bean对象中重写Comparable接口,对的你没看错,Comparable和Comparator 两个接口的区别在于Comparable是一个类需要内部实现,而Comparator 是外部调用的解析实现。2者都实现时sort方法优先外部调用,也就是Comparator 的compare,Comparator 和Comparable 的实现方法返回值含义相同,1排到后面,-1排到前面,0不变。

场景四:

求数组中某个value的index。好像终于可以摆脱自己for each的实现了,突然间就激动了起来呢。(滑稽)

Arrays.binarySearch()

传入数组和要查找的对象就可以了。对于实体bean的处理有几个点要注意下,
1.不像List集合重写equals方法,执行indexOf就能定位到索引,在binarySearch的源码中的实现方式很不幸的发现不是依赖于equals,而是基于二分查找和Comparable来实现的。
核心方法:

public static int binarySearch(Object[] array, int startIndex, int endIndex, Object value) {
        checkBinarySearchBounds(startIndex, endIndex, array.length);
        int lo = startIndex;
        int hi = endIndex - 1;

        while (lo <= hi) {
            int mid = (lo + hi) >>> 1;
            @SuppressWarnings("unchecked")
            int midValCmp = ((Comparable) array[mid]).compareTo(value);

            if (midValCmp < 0) {
                lo = mid + 1;
            } else if (midValCmp > 0) {
                hi = mid - 1;
            } else {
                return mid;  // value found
            }
        }
        return ~lo;  // value not present
    }

也就是说compareTo返回0的时候才能定位到准确的位置,笔者这里认为,compareTo去做一些equals的活有点不太妥当。Arrays.binarySearch()不过这个方法对于基本类型的索引还是值得一用的。

0x01 屏幕适配

这里补上笔者当初一个坑,

场景:

UI:开发我把图切好了,1x,2x,3x,够了吗(其实我是把给IOS的图顺便给你了)
我:够了够了,(我有dp约束,用一套不颗粒化就OK)
说完我就把2x的随手放到了drawable-hdpi里面,dp一约束,低分辨,中等分辨,高分辨一跑,OK收工,心中还窃喜,还给APK节省了点空间(^__^)
后来在一些新建的工程中研究控件的时候定位了到了这个问题,明明初始化只渲染一些背景图,Monitors 中显示占用内存100M+,最后笔者进行了一些测试

测试一:

ImageView控件,真机samsung S7,1440*2560,测试图片为真机截屏

放置路径wrap_content180dp*320dpGlide加载
drawable230.1228.011.3
drawable-mdpi230.3228.111.3
drawable-hdpi105.5104.311.3
drawable-xhdpi60.762.211.2
drawable-xxhdpi28.930.811.3
drawable-xxxhdpi18.119.911.0
测试二:

ImageView控件,真机samsung S7,1440*2560,测试图片为小图标

放置路径48px*48px128px*128px
drawable4.25.0
drawable-mdpi4.25.0
drawable-hdpi3.75.5
drawable-xhdpi4.35.3
drawable-xxhdpi4.35.1
drawable-xxxhdpi4.65.3
结论

对于大的图片例如启动界面,引导图片全屏图片,如果不用第三方图片框架加载一定要适配所有的drawable,以后内存溢出怎么死的都不知道。。小图标经笔者不完全测试不会有太大问题,虽然笔者更喜欢用svg,当然当path过于复杂则划不来了。

第二章暂时告一段落,如有错误,敬请指正!

敬畏耶和华是智慧的开端;认识至圣者便是聪明。 (箴言 9:10 和合本)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值