Android 通过二进制运算原理优化内存

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_34379015/article/details/72629665

Android内存优化

为什么要进行内存优化?

从Android手机开始发布,卡顿一直是这个系统的软肋,这也是用户最反感的地方之一。2GB运行内存的Android系统可能只相当于1GB IOS的系统内存。这其中有开发者滥用权限和后台的原因也有设计者本身设计所存在的漏洞,现在很多开发者提倡遵守《android绿色应用公约》。不滥用内存、权限及后台。但是这还不够,因为每个Android应用能用到的最大运行内存是128MB,要是不节省内存就可能应用卡顿的现象,甚至导致内存泄漏等问题。

怎么进行内存优化?

既然决定要优化内存了那么就得花点心思优化一下程序算法,今天我就简要的说一下怎么通过一个int值实现多种条件的选择。一般Android自定义一些东西的时候一些条件的选择,比如我在写一个程序需要选择一些条件,但是条件的个数是不确定。程序如下:

public class Test {

    private static final int TYPE_ONE=0x0001;

    private static final int TYPE_TWO=0x0020;

    private static final int TYPE_THERE=0x0300;

    private static final int TYPE_FOUR=0x4000;

    private void addCondition(int condition){

}

可以清晰的看出这个Test类里面有四个条件,要是我每次只条件一部分条件且数量不确定那么一般的思路就是用一个数组来装载这个条件数据,具体如下

    public void addCondition(int[] conditions){
        for(int condition conditions){
            switch (condition) {
                case TYPE_ONE:
                    System.out.println("条件1被选中");
                    break;
                case TYPE_TWO:
                    System.out.println("条件2被选中");
                    break;
                case TYPE_THERE:
                    System.out.println("条件3被选中");
                    break;
                case TYPE_FOUR:
                    System.out.println("条件4被选中");
                    break;
                default:
                    break;
            }
        }
    }

添加条件

    int[] condition=new int[2];
    condition[0]=TYPE_ONE;
    condition[1]=TYPE_FOER;
    addCondition(condition);

这样似乎很简单的就实现了我们想要的功能,但是这个东西使用了一个int[],来装载条件的缺点是:

  • int[] 类型需要的内存更多
  • 在添加条件的时候程序的可观性不是很好
  • 添加条件的时候代码量相对较多

那么有什么好的办法的去解决它呢。
最近我看了下Android系统5.0分析,并且也是简要的了解的计算机组成原理,对计算机通过硬件实现基本的四则运算有了简要的了解。
其中Android系统有时候为了减少内存的使用,会用一个值来表示多种数据。比如Android onMeasure方法中传入的两个int值widthMeasureSpec和heightMeasureSpec。这两者都能表达两个值得数据,比如widthMeasureSpec中存有widthSize和widthMode。同理heightMeasureSpec也是如此,其实现的原理也简单,mode存在二进制的高位,而size存在二进制的低位,那么就实现了一个值表达两个值得目的节省了设置多个变量或是换用数组等大内存的对象。既然了解了系统的一些做法,那么自然我们也是可以利用其原理去实现一些内存的优化问题。
就拿这个题来说。我们可以只给addCondition()设置一个int类型的参数,并实现多条件的选择。不过在此之前先来了解一些二进制的运算符号及其功能

运算符 名称 功能 演示
<< 左移运算 将二进制所有位数向左移动,可增大其绝对值,比如移动n位,相当于乘上2的n次方 0001<<2=0100
>> 右移运算 将二进制所有位数向右移动,低位移除,将减少其绝对值,比如移动n位,相当于int类型的数除以2的n次方 1000>>2=0010
| 异或运算 异或的运算法则为:0⊕0=0,1⊕0=1,0⊕1=1,1⊕1=0(同为0,异为1) 0100|1001=1101

仔细研究一下异或运算不难发现,异或运算就是把两个数中1都保留。比如

    00110101|1001100=01111101
    0 0 1 1 0 1 0 1
      1 0 0 1 1 0 0 
    0 1 1 1 1 1 0 1

这就能很清晰的了解其特点了,两者相同位数的两个值只有有1那么结果中对应的位数就为1
那么再回头想想我们要实现的功能,我们是不是可以把两个数异或然后达到多种条件选择的效果,比如01为条件1,10为条件2,那么两者异或就得到11,是不是就表达了两个条件都被选中的效果了?
既然简要的明白了思量那么我们就来实现上面所需要的功能。代码如下:

public class Test {

    private static final int TYPE_ONE=0x0001;

    private static final int TYPE_TWO=0x0020;

    private static final int TYPE_THERE=0x0300;

    private static final int TYPE_FOUR=0x4000;

    private void addCondition(int condition){

        while(condition>=TYPE_ONE){


            switch (condition%0x10) {

            case TYPE_ONE:
                System.out.println("条件1被选中");
                break;
            case TYPE_TWO>>4:
                System.out.println("条件2被选中");
                break;
            case TYPE_THERE>>8:
                System.out.println("条件3被选中");
                break;
            case TYPE_FOUR>>12:
                System.out.println("条件4被选中");
                break;
            default:
                break;
            }
            condition=condition>>4;
        }

    }
}

再看看是否能达到我们所需要的效果

    Test test=new Test();
    test.addCondition(TYPE_FOUR|TYPE_THERE);

运行效果
这里写图片描述

    Test test=new Test();
    test.addCondition(TYPE_ONE|TYPE_THERE|TYPE_FOUR);

这里写图片描述
看来运行是没有问题的,这时候我们来分析一下怎么实现的,首先要明白一下Android中不可以直接使用二进制的,那么就简要的拿十六进制的来代替一下。十六进制相对于二进制也比较好转化。
先把前面四个条件变量转成二进制来分析一下
PS:空格是为了使16进制转化为2进制看起来更清晰,无其他含义

TYPE_ONE=0x0001;(0000 0000 0000 0001)

TYPE_TWO=0x0020;(0000 0000 0010 0000)

TYPE_THERE=0x0300;(0000 0011 0000 0000)

TYPE_FOUR=0x4000;(0100 0000 0000 0000)

仔细思考一下就可以得出一个小规律——任意几个条件异或运算后都能得出一个独特的二进制,而且其每四位为一个单位可以通过移位和mod16实现每个条件的添加。
如TYPE_ONE|TYPE_TWO=0000 0000 0010 0001 mod16后得0001,及条件1被选中
然后右移4位得0000 0000 0000 0010,继续mode16得0010,及条件2被选中,继续移位直到其值小于TYPE_ONE结束。

优化后的对比

前面介绍了两种方法,第一种比较耗内存并且不能直观的表达程序的含义,第二种比较灵活且能直接表达条件的选择。两者对CPU的消耗可能第二者略高,但是纵观计算机的发展史,CPU的发展速度远高于存储器的发展速度,所以这样的交换是合算。同时可能一些读者可能会觉得<<4就相当于乘以16,那为什么那么麻烦的去用移位呢? 其实这两者虽然效果差不多,但是其中原理还是有很大区别的,如果使用的是乘以16,那么整个运算需要移4位并进行4次加法运算(有疑问可以详细了解),那么显而易见,还是<<比乘法好,但是<<的缺陷就是其运算仅限于2及其的次方。

总结

所谓学以致用,既然我学习了计算机组成原理和一些Android系统优化,自然是可以将这种小细节应用在我的项目中,不要认为其作用小而忽略,有时候细节能决定成败的!有更好的想法的读者可以一起讨论一下,好东西需要分享的。

猜你喜欢

转载自blog.csdn.net/qq_34379015/article/details/72629665