ART世界探险(5) - 计算指令

ART世界探险(5) - 计算指令

整数运算

Java的整型运算

我们先看看JVM是如何处理这些基本整数运算的吧。

    public static long add(long a, long b){
        return a+b;
    }

    public static long sub(long a,long b){
        return a-b;
    }

    public static long mul(long a, long b){
        return a*b;
    }

    public static long div(long a,long b){
        return a/b;
    }

    public static long mod(long a,long b){
        return a%b;
    }

翻译成字节码是这样的,非常整齐:

  public static long add(long, long);
    Code:
       0: lload_0
       1: lload_2
       2: ladd
       3: lreturn

  public static long sub(long, long);
    Code:
       0: lload_0
       1: lload_2
       2: lsub
       3: lreturn

  public static long mul(long, long);
    Code:
       0: lload_0
       1: lload_2
       2: lmul
       3: lreturn

  public static long div(long, long);
    Code:
       0: lload_0
       1: lload_2
       2: ldiv
       3: lreturn

  public static long mod(long, long);
    Code:
       0: lload_0
       1: lload_2
       2: lrem
       3: lreturn

加是add,减是sub,乘是mul,除是div,取模是rem。

我们看看在ARM上的实现。

ARM的整型运算

C++代码和Java基本上是同出一辙的:

long add(long a, long b){
    return a+b;
}

long sub(long a,long b){
    return a-b;
}

long mul(long a, long b){
    return a*b;
}

long div(long a,long b){
    return a/b;
}

long mod(long a,long b){
    return a%b;
}

ARM v8a的整数运算

我们看看在AArch64下译成什么:

0000000000000694 <_Z3addll>:
 694:   8b010000    add x0, x0, x1
 698:   d65f03c0    ret

000000000000069c <_Z3subll>:
 69c:   cb010000    sub x0, x0, x1
 6a0:   d65f03c0    ret

00000000000006a4 <_Z3mulll>:
 6a4:   9b017c00    mul x0, x0, x1
 6a8:   d65f03c0    ret

00000000000006ac <_Z3divll>:
 6ac:   9ac10c00    sdiv    x0, x0, x1
 6b0:   d65f03c0    ret

00000000000006b4 <_Z3modll>:
 6b4:   9ac10c02    sdiv    x2, x0, x1
 6b8:   9b018040    msub    x0, x2, x1, x0
 6bc:   d65f03c0    ret

ARM v7a的整数运算

AArch32模式下,加减乘都是一条指令

00000fc0 <_Z3addll>:
     fc0:   4408        add r0, r1
     fc2:   4770        bx  lr

00000fc4 <_Z3subll>:
     fc4:   1a40        subs    r0, r0, r1
     fc6:   4770        bx  lr

00000fc8 <_Z3mulll>:
     fc8:   4348        muls    r0, r1
     fca:   4770        bx  lr

但是除法和取模就不是指令了,得调用函数来处理。

00000fcc <_Z3divll>:
     fcc:   b508        push    {r3, lr}
     fce:   f000 e830   blx 1030 <__aeabi_idiv>
     fd2:   bd08        pop {r3, pc}

00000fd4 <_Z3modll>:
     fd4:   b508        push    {r3, lr}
     fd6:   f000 e89a   blx 110c <__aeabi_idivmod>
     fda:   4608        mov r0, r1
     fdc:   bd08        pop {r3, pc}

算除法的这个函数可是不短啊,我们先看一下,这个将来可供我们学完指令集之后复习用:

00001030 <__aeabi_idiv>:
    1030:   e3510000    cmp r1, #0
    1034:   0a000030    beq 10fc <__aeabi_idiv+0xcc>
    1038:   e020c001    eor ip, r0, r1
    103c:   42611000    rsbmi   r1, r1, #0
    1040:   e2512001    subs    r2, r1, #1
    1044:   0a00001f    beq 10c8 <__aeabi_idiv+0x98>
    1048:   e1b03000    movs    r3, r0
    104c:   42603000    rsbmi   r3, r0, #0
    1050:   e1530001    cmp r3, r1
    1054:   9a00001e    bls 10d4 <__aeabi_idiv+0xa4>
    1058:   e1110002    tst r1, r2
    105c:   0a000020    beq 10e4 <__aeabi_idiv+0xb4>
    1060:   e16f2f11    clz r2, r1
    1064:   e16f0f13    clz r0, r3
    1068:   e0420000    sub r0, r2, r0
    106c:   e3a02001    mov r2, #1
    1070:   e1a01011    lsl r1, r1, r0
    1074:   e1a02012    lsl r2, r2, r0
    1078:   e3a00000    mov r0, #0
    107c:   e1530001    cmp r3, r1
    1080:   20433001    subcs   r3, r3, r1
    1084:   21800002    orrcs   r0, r0, r2
    1088:   e15300a1    cmp r3, r1, lsr #1
    108c:   204330a1    subcs   r3, r3, r1, lsr #1
    1090:   218000a2    orrcs   r0, r0, r2, lsr #1
    1094:   e1530121    cmp r3, r1, lsr #2
    1098:   20433121    subcs   r3, r3, r1, lsr #2
    109c:   21800122    orrcs   r0, r0, r2, lsr #2
    10a0:   e15301a1    cmp r3, r1, lsr #3
    10a4:   204331a1    subcs   r3, r3, r1, lsr #3
    10a8:   218001a2    orrcs   r0, r0, r2, lsr #3
    10ac:   e3530000    cmp r3, #0
    10b0:   11b02222    lsrsne  r2, r2, #4
    10b4:   11a01221    lsrne   r1, r1, #4
    10b8:   1affffef    bne 107c <__aeabi_idiv+0x4c>
    10bc:   e35c0000    cmp ip, #0
    10c0:   42600000    rsbmi   r0, r0, #0
    10c4:   e12fff1e    bx  lr
    10c8:   e13c0000    teq ip, r0
    10cc:   42600000    rsbmi   r0, r0, #0
    10d0:   e12fff1e    bx  lr
    10d4:   33a00000    movcc   r0, #0
    10d8:   01a00fcc    asreq   r0, ip, #31
    10dc:   03800001    orreq   r0, r0, #1
    10e0:   e12fff1e    bx  lr
    10e4:   e16f2f11    clz r2, r1
    10e8:   e262201f    rsb r2, r2, #31
    10ec:   e35c0000    cmp ip, #0
    10f0:   e1a00233    lsr r0, r3, r2
    10f4:   42600000    rsbmi   r0, r0, #0
    10f8:   e12fff1e    bx  lr
    10fc:   e3500000    cmp r0, #0
    1100:   c3e00102    mvngt   r0, #-2147483648    ; 0x80000000
    1104:   b3a00102    movlt   r0, #-2147483648    ; 0x80000000
    1108:   ea000007    b   112c <__aeabi_idiv0>

0000110c <__aeabi_idivmod>:
    110c:   e3510000    cmp r1, #0
    1110:   0afffff9    beq 10fc <__aeabi_idiv+0xcc>
    1114:   e92d4003    push    {r0, r1, lr}
    1118:   ebffffc6    bl  1038 <__aeabi_idiv+0x8>
    111c:   e8bd4006    pop {r1, r2, lr}
    1120:   e0030092    mul r3, r2, r0
    1124:   e0411003    sub r1, r1, r3
    1128:   e12fff1e    bx  lr

传统armeabi的整数运算

加减乘还是没有问题:adds,subs,muls,改状态位。

00001248 <_Z3addll>:
    1248:   1840        adds    r0, r0, r1
    124a:   4770        bx  lr

0000124c <_Z3subll>:
    124c:   1a40        subs    r0, r0, r1
    124e:   4770        bx  lr

00001250 <_Z3mulll>:
    1250:   4348        muls    r0, r1
    1252:   4770        bx  lr

除法和取模也是调函数:

00001254 <_Z3divll>:
    1254:   b508        push    {r3, lr}
    1256:   f001 ff47   bl  30e8 <_Unwind_GetTextRelBase+0x8>
    125a:   bd08        pop {r3, pc}

0000125c <_Z3modll>:
    125c:   b508        push    {r3, lr}
    125e:   f001 ff4b   bl  30f8 <_Unwind_GetTextRelBase+0x18>
    1262:   1c08        adds    r0, r1, #0
    1264:   bd08        pop {r3, pc}

浮点运算

Java浮点运算

Java真是门好语言啊,JVM已经封装了所有跟浮点相关的细节,基本上从字节码上看,跟长整型只有细节的不同。

    public static double dadd(double a,double b){
        return a+b;
    }

    public static double dsub(double a,double b){
        return a-b;
    }

    public static double dmul(double a,double b){
        return a*b;
    }

    public static double ddiv(double a,double b){
        return a/b;
    }

字节码如下:

  public static double dadd(double, double);
    Code:
       0: dload_0
       1: dload_2
       2: dadd
       3: dreturn

  public static double dsub(double, double);
    Code:
       0: dload_0
       1: dload_2
       2: dsub
       3: dreturn

  public static double dmul(double, double);
    Code:
       0: dload_0
       1: dload_2
       2: dmul
       3: dreturn

  public static double ddiv(double, double);
    Code:
       0: dload_0
       1: dload_2
       2: ddiv
       3: dreturn

基本上就是将l换成d,其它没有什么变化。

ARM浮点运算

强大的ARM v8A芯片,已经不输于JVM的设计了,也是很简单。
源代码:

double dadd(double a,double b){
    return a+b;
}

double dsub(double a,double b){
    return a-b;
}

double dmul(double a,double b){
    return a*b;
}

double ddiv(double a,double b){
    return a/b;
}

ARM v8a的浮点运算

汇编代码:

0000000000000760 <_Z4dadddd>:
 760:   1e612800    fadd    d0, d0, d1
 764:   d65f03c0    ret

0000000000000768 <_Z4dsubdd>:
 768:   1e613800    fsub    d0, d0, d1
 76c:   d65f03c0    ret

0000000000000770 <_Z4dmuldd>:
 770:   1e610800    fmul    d0, d0, d1
 774:   d65f03c0    ret

0000000000000778 <_Z4ddivdd>:
 778:   1e611800    fdiv    d0, d0, d1
 77c:   d65f03c0    ret

我们可以看到,寄存器已经不是x开头的通用寄存器了,而变成了d开头的NEON寄存器。我们实际上是借用了ARM v7a才出现的NEON指令才使得指令变得这么简单。

ARM v7a的浮点运算:

同样是NEON指令,但是v7a的就比v8a的看起来要复杂一点。不过倒更清晰地反映了逻辑事实。
v7a的NEON指令需要用vmov将通用寄存器中的数传送到NEON寄存器中,然后再进行计算。结果再通过vmov送回到通用寄存器中。

00000fde <_Z4dadddd>:
     fde:   ec41 0b17   vmov    d7, r0, r1
     fe2:   ec43 2b16   vmov    d6, r2, r3
     fe6:   ee37 7b06   vadd.f64    d7, d7, d6
     fea:   ec51 0b17   vmov    r0, r1, d7
     fee:   4770        bx  lr

00000ff0 <_Z4dsubdd>:
     ff0:   ec41 0b17   vmov    d7, r0, r1
     ff4:   ec43 2b16   vmov    d6, r2, r3
     ff8:   ee37 7b46   vsub.f64    d7, d7, d6
     ffc:   ec51 0b17   vmov    r0, r1, d7
    1000:   4770        bx  lr

00001002 <_Z4dmuldd>:
    1002:   ec41 0b17   vmov    d7, r0, r1
    1006:   ec43 2b16   vmov    d6, r2, r3
    100a:   ee27 7b06   vmul.f64    d7, d7, d6
    100e:   ec51 0b17   vmov    r0, r1, d7
    1012:   4770        bx  lr

00001014 <_Z4ddivdd>:
    1014:   ec41 0b17   vmov    d7, r0, r1
    1018:   ec43 2b16   vmov    d6, r2, r3
    101c:   ee87 7b06   vdiv.f64    d7, d7, d6
    1020:   ec51 0b17   vmov    r0, r1, d7
    1024:   4770        bx  lr

传统ARM的浮点运算

没啥说的,都得函数实现了:

00001248 <_Z3addll>:
    1248:   1840        adds    r0, r0, r1
    124a:   4770        bx  lr

0000124c <_Z3subll>:
    124c:   1a40        subs    r0, r0, r1
    124e:   4770        bx  lr

00001250 <_Z3mulll>:
    1250:   4348        muls    r0, r1
    1252:   4770        bx  lr

00001254 <_Z3divll>:
    1254:   b508        push    {r3, lr}
    1256:   f001 ff47   bl  30e8 <_Unwind_GetTextRelBase+0x8>
    125a:   bd08        pop {r3, pc}

0000125c <_Z3modll>:
    125c:   b508        push    {r3, lr}
    125e:   f001 ff4b   bl  30f8 <_Unwind_GetTextRelBase+0x18>
    1262:   1c08        adds    r0, r1, #0
    1264:   bd08        pop {r3, pc}

x86芯片的运算指令

几种ARM下的RISC指令集的结果,我们都分析过了。下面我们看看32位的x86芯片上的整数和浮点运算吧。

x86的整数运算

32位的标志是使用32位的寄存器,比如eax,esp,esi。而64位下就是rax等等了。

00005f0 <_Z3addll>:
 5f0:   8b 44 24 08             mov    0x8(%esp),%eax
 5f4:   03 44 24 04             add    0x4(%esp),%eax
 5f8:   c3                      ret    
 5f9:   8d b4 26 00 00 00 00    lea    0x0(%esi,%eiz,1),%esi

00000600 <_Z3subll>:
 600:   8b 44 24 04             mov    0x4(%esp),%eax
 604:   2b 44 24 08             sub    0x8(%esp),%eax
 608:   c3                      ret    
 609:   8d b4 26 00 00 00 00    lea    0x0(%esi,%eiz,1),%esi

00000610 <_Z3mulll>:
 610:   8b 44 24 08             mov    0x8(%esp),%eax
 614:   0f af 44 24 04          imul   0x4(%esp),%eax
 619:   c3                      ret    
 61a:   8d b6 00 00 00 00       lea    0x0(%esi),%esi

00000620 <_Z3divll>:
 620:   8b 44 24 04             mov    0x4(%esp),%eax
 624:   89 c2                   mov    %eax,%edx
 626:   c1 fa 1f                sar    $0x1f,%edx
 629:   f7 7c 24 08             idivl  0x8(%esp)
 62d:   c3                      ret    
 62e:   66 90                   xchg   %ax,%ax

00000630 <_Z3modll>:
 630:   8b 44 24 04             mov    0x4(%esp),%eax
 634:   89 c2                   mov    %eax,%edx
 636:   c1 fa 1f                sar    $0x1f,%edx
 639:   f7 7c 24 08             idivl  0x8(%esp)
 63d:   89 d0                   mov    %edx,%eax
 63f:   c3                      ret    

x86的CISC的好处是总不至于要调一段复杂的函数来实现除法。

x86_64的整数运算

我们看看64位的rn寄存器出场之后的x86_64的整型指令吧:

00000000000006e0 <_Z3addll>:
 6e0:   48 8d 04 37             lea    (%rdi,%rsi,1),%rax
 6e4:   c3                      retq   
 6e5:   66 66 2e 0f 1f 84 00    data16 nopw %cs:0x0(%rax,%rax,1)
 6ec:   00 00 00 00 

00000000000006f0 <_Z3subll>:
 6f0:   48 89 f8                mov    %rdi,%rax
 6f3:   48 29 f0                sub    %rsi,%rax
 6f6:   c3                      retq   
 6f7:   66 0f 1f 84 00 00 00    nopw   0x0(%rax,%rax,1)
 6fe:   00 00 

0000000000000700 <_Z3mulll>:
 700:   48 89 f8                mov    %rdi,%rax
 703:   48 0f af c6             imul   %rsi,%rax
 707:   c3                      retq   
 708:   0f 1f 84 00 00 00 00    nopl   0x0(%rax,%rax,1)
 70f:   00 

0000000000000710 <_Z3divll>:
 710:   48 89 fa                mov    %rdi,%rdx
 713:   48 89 f8                mov    %rdi,%rax
 716:   48 c1 fa 3f             sar    $0x3f,%rdx
 71a:   48 f7 fe                idiv   %rsi
 71d:   c3                      retq   
 71e:   66 90                   xchg   %ax,%ax

0000000000000720 <_Z3modll>:
 720:   48 89 fa                mov    %rdi,%rdx
 723:   48 89 f8                mov    %rdi,%rax
 726:   48 c1 fa 3f             sar    $0x3f,%rdx
 72a:   48 f7 fe                idiv   %rsi
 72d:   48 89 d0                mov    %rdx,%rax
 730:   c3                      retq   
 731:   66 66 66 66 66 66 2e    data16 data16 data16 data16 data16 nopw %cs:0x0(%rax,%rax,1)
 738:   0f 1f 84 00 00 00 00 
 73f:   00 

x86的符点运算

从30多年前的80486开始,x86芯片就自带FPU,不再需要8087或者80387这样的专用FPU。1998年,AMD在k6-2处理器中使用的3D Now!指令集开创了SIMD与浮点数的结合。1999年,Intel也随之推出了支持单精度浮点的SSE指令。后来一直发展到SSE 4.2.
以我们的双精度计算的例子为例,这使用到了2000年发布的Pentium 4才引入的SSE2指令集。movsd,addsd,divsd等这些指令都是SSE2指令。

00000640 <_Z4dadddd>:
 640:   8d 64 24 f4             lea    -0xc(%esp),%esp
 644:   f2 0f 10 44 24 18       movsd  0x18(%esp),%xmm0
 64a:   f2 0f 58 44 24 10       addsd  0x10(%esp),%xmm0
 650:   f2 0f 11 04 24          movsd  %xmm0,(%esp)
 655:   dd 04 24                fldl   (%esp)
 658:   8d 64 24 0c             lea    0xc(%esp),%esp
 65c:   c3                      ret    
 65d:   8d 76 00                lea    0x0(%esi),%esi

00000660 <_Z4dsubdd>:
 660:   8d 64 24 f4             lea    -0xc(%esp),%esp
 664:   f2 0f 10 44 24 10       movsd  0x10(%esp),%xmm0
 66a:   f2 0f 5c 44 24 18       subsd  0x18(%esp),%xmm0
 670:   f2 0f 11 04 24          movsd  %xmm0,(%esp)
 675:   dd 04 24                fldl   (%esp)
 678:   8d 64 24 0c             lea    0xc(%esp),%esp
 67c:   c3                      ret    
 67d:   8d 76 00                lea    0x0(%esi),%esi

00000680 <_Z4dmuldd>:
 680:   8d 64 24 f4             lea    -0xc(%esp),%esp
 684:   f2 0f 10 44 24 18       movsd  0x18(%esp),%xmm0
 68a:   f2 0f 59 44 24 10       mulsd  0x10(%esp),%xmm0
 690:   f2 0f 11 04 24          movsd  %xmm0,(%esp)
 695:   dd 04 24                fldl   (%esp)
 698:   8d 64 24 0c             lea    0xc(%esp),%esp
 69c:   c3                      ret    
 69d:   8d 76 00                lea    0x0(%esi),%esi

000006a0 <_Z4ddivdd>:
 6a0:   8d 64 24 f4             lea    -0xc(%esp),%esp
 6a4:   f2 0f 10 44 24 10       movsd  0x10(%esp),%xmm0
 6aa:   f2 0f 5e 44 24 18       divsd  0x18(%esp),%xmm0
 6b0:   f2 0f 11 04 24          movsd  %xmm0,(%esp)
 6b5:   dd 04 24                fldl   (%esp)
 6b8:   8d 64 24 0c             lea    0xc(%esp),%esp
 6bc:   c3                      ret    
 6bd:   8d 76 00                lea    0x0(%esi),%esi

x86_64的浮点运算

与arm64有异曲同工之妙,不再需要进出xmm的时候做movsd了,retq指令可以直接从xmm寄存器中返回数据。

0000000000000740 <_Z4dadddd>:
 740:   f2 0f 58 c1             addsd  %xmm1,%xmm0
 744:   c3                      retq   
 745:   66 66 2e 0f 1f 84 00    data16 nopw %cs:0x0(%rax,%rax,1)
 74c:   00 00 00 00 

0000000000000750 <_Z4dsubdd>:
 750:   f2 0f 5c c1             subsd  %xmm1,%xmm0
 754:   c3                      retq   
 755:   66 66 2e 0f 1f 84 00    data16 nopw %cs:0x0(%rax,%rax,1)
 75c:   00 00 00 00 

0000000000000760 <_Z4dmuldd>:
 760:   f2 0f 59 c1             mulsd  %xmm1,%xmm0
 764:   c3                      retq   
 765:   66 66 2e 0f 1f 84 00    data16 nopw %cs:0x0(%rax,%rax,1)
 76c:   00 00 00 00 

0000000000000770 <_Z4ddivdd>:
 770:   f2 0f 5e c1             divsd  %xmm1,%xmm0
 774:   c3                      retq   
 775:   66 66 2e 0f 1f 84 00    data16 nopw %cs:0x0(%rax,%rax,1)
 77c:   00 00 00 00 

MIPS指令集下的计算指令

最后我们看下可能多数同学们都不熟悉的MIPS指令集吧,其实还是很清爽的:

000006b0 <_Z3addll>:
 6b0:   03e00008    jr  ra
 6b4:   00851021    addu    v0,a0,a1

000006b8 <_Z3subll>:
 6b8:   03e00008    jr  ra
 6bc:   00851023    subu    v0,a0,a1

000006c0 <_Z3mulll>:
 6c0:   03e00008    jr  ra
 6c4:   70851002    mul v0,a0,a1

000006c8 <_Z3divll>:
 6c8:   0085001a    div zero,a0,a1
 6cc:   00a001f4    teq a1,zero,0x7
 6d0:   03e00008    jr  ra
 6d4:   00001012    mflo    v0

000006d8 <_Z3modll>:
 6d8:   0085001a    div zero,a0,a1
 6dc:   00a001f4    teq a1,zero,0x7
 6e0:   03e00008    jr  ra
 6e4:   00001010    mfhi    v0

000006e8 <_Z4dadddd>:
 6e8:   03e00008    jr  ra
 6ec:   462e6000    add.d   $f0,$f12,$f14

000006f0 <_Z4dsubdd>:
 6f0:   03e00008    jr  ra
 6f4:   462e6001    sub.d   $f0,

本页内容版权归属为原作者,如有侵犯您的权益,请通知我们删除。
大部分的软件, 但凡包含登录注册的, 基本都会有选择头像功能, 而其中做的比较有逼格的, 一般会有一个选择框可以裁剪照片。 本文所需要实现的就是这样一种有 逼格 的效果: 右上角加了个图片框,按下确定可以裁剪正方形区域里的图片并显示在右上角。 实现思路: 1:首先需要自定义一个ZoomImageView来显示我们需要的图片,这个View需要让图片能够以合适的位置展现在当前布局的图片展示区域内(合适的位置值的是:如果图片长度大于屏幕,则压缩图片长度至屏幕宽度,高度等比压缩并居中显示,如果图片高度大于屏幕,则

注解使用入门(一) - 2016-07-25 18:07:18

注解使用入门(一) 本篇博客要讲解主要分为以下几个问题 注解的相关知识点 基于运行时的注解的例子解析说明 至于关于编译时的注解,待下篇博客的时候会结合例子讲解一下,目前我也正在学习当中 注解的相关知识点 提到注解,大多数人应该都不默认,在我们程序中见到的@Override,@Deprected,@SupressWarnings等等,这些都是注解,只不过是系统自己封装好的,而我们平时比较少去深入理解是怎样实现的? 1)什么是注解(Annotation): Annotation(注解)就是Java提供了一种元

android-----我眼中的Binder - 2016-07-25 18:07:17

        Binder作为进程间通信方式(IPC)的一种,算Android中比较难理解的部分了,今天计划以自己所认识的framework层的Binder原理来做个总结,好了,我们开始吧!         Android中利用Binder通信,首先肯定需要获得Binder对象了,但是系统服务和我们自定义服务Binder对象的获取方式是不一样的,原因就在于系统服务是在系统启动的时候被注册到ServiceManegr的,我们只需要通过ServiceManager.getService(String nam
使用xml作为数据交互的载体是Android中非常重要的功能,比如天气预报数据、短信备份数据、通讯录数据都可以以xml的格式通过网络传输。 为了演示Xml数据的操作,我模拟了一个短信备份的案例。 需求:界面如图1-10所示。上面是三个Button,前两个分别对应两种不同方式生成xml,第三个Button点击后解析备份的xml文件,然后将数据展现在下面的ScrollView中。短信数据是模拟的假数据。 生成的xml格式如文件1-10。 【文件1-10】 xml文件格式 1. ?xml version="1.
这篇博客我们来介绍一下责任链模式(Chain-of-responsibility Pattern),责任联模式又称为职责链模式,是 行为型设计模式 之一。顾名思义,责任链模式中存在一个链式结构,多个节点首尾相连,每个节点都可以被拆开再连接,因此,链式结构具有很好的灵活性。将这样一种结构应用于编程领域,将每一个节点看作是一个对象,每一个对象拥有不同的处理逻辑,将一个请求从链式的首段发出,沿着链的路径依次传递给每一个节点对象,直至有对象处理这个请求为止,这就是责任链或者职责链的通俗定义。 转载请注明出处: h

GeekBand第十一周笔记 - 2016-07-25 17:07:19

本周的主要内容介绍Gradle,NDK,管理依赖和Git等 一、Gradle Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化建构工具。它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于XML的各种繁琐配置。 面向Java应用为主。当前其支持的语言限于Java、Groovy和Scala,计划未来将支持更多的语言。 Coding只是软件开发中的一个部分 编译源代码 运行单元测试和集成测试 执行静态代码分析,生成分析报告 创建分布版本 部署到目标环
在安卓开发中,谷歌已经为我们提供了许多原生控件,基本上能够满足我们日常的开发需求,但是某些项目中原生控件可能达不到产品所要求的各式各样的酷炫效果或功能效果,这个时候我们只能自己自定义控件来满足项目需求,我们知道自定义控件包括三种方式: 1继承控件,即继承谷歌提供的原生控件,在此基础上提供一些原生控件不具备的功能,如github上各种酷炫效果的开源组件基本上都是采用的这种方式. 2组合控件:即组合多个原生控件来达到某些单个原生控件原本不具备的功能,这个在日常开发中应该是使用的比较多的,如基本上每个App都存

Android多点触摸交互处理 - 2016-07-25 17:07:15

安卓手机中,多点触摸是是最基本的操作,下面就使用程序进行演示多点触摸操作 一、获取触摸事件中的点击,移动和抬起事件,创建新的安卓项目,如下面代码所示,分别为MainActivity类代码和Layout布局文件,用于实现获取点击事件 1.1、MainActivity类中代码,代码中为布局对象root添加监听事件,使用switch进行对屏幕时间进行判断,用于判断事件的按下还是移动,在代码中      root=(RelativeLayout) findViewById(R.id.content);用于绑定布局
内容是博主照着书敲出来的,博主码字挺辛苦的,转载请注明出处,后序内容陆续会码出。 前言:ListView——列表,它作为一个非常重要的显示方式,不管是在Web中还是移动平台中,都是一个非常好的、不开或缺的展示信息的工具。在Android中,ListView控件接管了这一重担,在大量的场合下,我们都需要使用这个控件。虽然在Android 5.X时代,RecyclerView在很多地方都在逐渐取代ListView,但ListView的使用范围依然非常的广泛,它这万年老大哥的地位也不是轻易就能撼动的。下面就介绍
Android ListView使用简介 ListView 是 Android 软件开发中十分常用也十分重要的一个 UI 控件。 ListView 的每一个子项可以是一个简单的字符串,也可以是一组 View 的组合,开发者完全可以根据自己的需求来定义显示的形式。 如何使用一个 ListView 实现对数据的显示呢 ? 1. 创建 ListView 控件,已备数据显示 2. 准备要显示的数据 3. 为 ListView 构建一个数据适配器 (Adapter) 4. 绑定适配器 5. 处理 ListView