Android优化学习篇一:NDK的那些事儿

前言

本文是基于学习Design and Implementation of Android:Volume 1Pro Android Apps Preformance Optimization 的学习总结。如果有错误之处,请多多指教。

基础知识

在学习Android 优化前,我简要分析一下Android的体系结构和框架基础。

1.关于Android Linux内核层

Android自ICS(Ice Cream Sandwich,指4.0.1-4.0.2)开始便基于Linux3.0内核,充分利用了Linux内核基于权限的安全模型、内存管理、进程管理、网络协议栈和驱动模型的优点,并且在Low Memory Killer、进程间通信(Binder)、电源管理以及日志系统(Logger)等方面引入不同于标准Linux的全新实现。Android对标准Linux内核做了大量剪裁和优化,其中主要集中于以下的方面:
弃用标准的Linux的GUI系统。
采用更有效率的Bionic Libc库代替glibc库。
基于ARM架构增加了Gold-Fish平台(一种虚拟的ARM处理器,在Android的仿真环境中使用)
专有的驱动程序:Binder、Logger、PowerManager。

2.动态视角的体系结构

Google工程狮是Sans Serif是这样描述的,如图:
这里写图片描述
来自:https://www.tbray.org/ongoing/When/201x/2010/11/14/What-Android-Is

开发者空间

在开发者空间中分为两个交互的子系统:Native子系统和Java子系统。两个子系统通过JNI连接在一起,建立在内核空间之上。

内核空间

内核空间分为两部分:Linux内核和Android扩展支持。

NDK的支持问题

NDK包括多个平台以及不同版本的预编译库。譬如NDKr7支持以下三个应用程序的二进制接口(ABI)。
armeabi
armeabi-v7a
x86
其中,x86表示因特尔架构系列的CPU。而armeabi-v7a则是从洗衣机到DVD播放器都有的ARM芯片系列。”armeabi”表示ARM应用程序二进制接口。当然,v5和v7是指两种不同的架构。要提下,Cortex系列属于ARMv7架构,这是到2010年为止ARM公司最新的指令集架构。到了现在,ARM不仅在Cortex-A9和Cortex-A15架构的CPU芯片方面很给力,在亲儿子的GPU系列Mali也发展迅速。从Galaxy S2上的Mali-400mp4开始让人熟知,后来发展到Mali-T6XX(这个系列使用的产品不多)。而10月30日ARM也终于发布了全新的Mali-T7XX系列,其中旗舰产品为Mali-T760,也是三星GALAXY S6的CPU型号。

对于不兼容的情况,譬如:
我们在Application.mk只定了构建版本的一个库,譬如:APP_ABI:=armeabi,对Cortex系列的处理器,则不能兼容或者本地代码与X86 ABI不兼容。这时候,如果本地代码是必要的,那么应用将不能在任何机遇Intel的Android设备上工作。
可以使用一下两个方法解决:
1、只要NDK增加新的ABI,就重新编译库并发布更新。
2、保留一个JAVA版本的实现方法。
譬如,使用策略模式的java实现的Fibonacci。

//FibonacciInterface.java
public interface FibonacciInterface{
    public long long fibonacci(int n);
}

//FibonacciInterface implements FibonacciInterface{
    public long long fibonacci(int n){
        int pre = 0;
        int next = 1;
        int temp = 0;
        for(int i = 2 ; i < n ; i++){
            temp = pre ;
            pre = next;
            next += temp ;
        }
        return (long long)next;
    }
}

//在本地代码兼容时使用
public final class FibonacciNative implements FibonacciInterface{
    static{
        System.loadLibary("fibonacci");//本地实现fibonacci库
    }
    public native long long fibonacci(int n);
}

//Main
public class Fibonacci{
    private static final FibonacciInterface fibStrategy;
    static{
    FibonacciInterface fib;
    try{
        fib = new FibonacciNative();
    catch(Throwable e){
        fib = new FibonacciJava();
    }
    fibStrategy = fib;
    }

    public static long long fibonacci(int n){
        return fibStrategy.fibonacci(n);
    }
}

使用C/C++与Java的较量

C/C++的效率并不一定比Java好。而Davlik JIT也可以生成本地代码,甚至可能比你的本地代码还要高效。即时编译(Just-in-time Compilation,JIT),又称动态转译(Dynamic Translation),是一种通过在运行时将字节码翻译为机器码,从而改善字节码编译语言性能的技术。即时编译前期的两个运行时理论是字节码编译和动态编译。Android原来Dalvik虚拟机是作为一种解释器实现,新版(Android2.2+)将换成JIT编译器实现。性能测试显示,在多项测试中新版本比旧版本提升了大约6倍。
在安卓的几次大的版本升级中,从4.4加入art模式到5.0默认art模式,这对安卓系统是一个质的飞跃,安卓的流畅性终于可以和iOS一较高低了。ART模式与此前安卓的Dalvik模式最大的不同在于,在启用ART模式后,系统在安装应用的时候会进行一次预编译,在安装应用程序时会先将代码转换为机器语言存储在本地,这样在运行程序时就不会每次都进行一次编译,执行效率也大大提升。而此前的Dalvik模式在每次启动应用时将程序的语言由高级语言编译为机器语言,这样当前设备才能够运行这一应用,启动速度会相比art模式大大降低。
说到底,本地的实现不一定比启用JIT的Java版本快。除非遇到下面所说的,你就可以考虑本地代码了。

使用NDK优化的理由

1.对于Android 2.1或者更早的版本而言,优化策略就更重要了。因为2.1以前是没有JIT的。
2.NDK对于代码的保护是十分重要的,使用NDK,我们可以将需要保密的应用逻辑使用C/C++开发。毕竟,Java包都是可以反编译的。
3.频繁占用CPU但是申请的内存空间不是很大的操作,像信号的处理,物体的模拟等等。简单的用C/C++重写我们的代码是不会带来很大的性能提升的。对比Java的对象的创建于销毁的开销,这方面确实比不上本地代码。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值