CSDN:初学Android的时候,很多人搞不清Android和Java到底有什么不同,你认为他们之间的区别是什么呢?另外,Android内核跟linux又有什么区别? 罗升阳:实际上,Android是Android,Java是Java。不用Java,用C/C++写的程序,也一样可以在Android上运行。对于这个问题,其实不只是初学者,对于不少有经验的开发者,也会认为做Android应用开发,懂Java就行了。从最近面试的一些人来看,就很明显地感觉到这个问题的普遍性。很多Android应用开发者只懂得使用Android SDK提供的Java接口来开发东西,但是没有进一步去学习一些更深层次的东西。 本质上说,Android是一个Linux系统,因此它是基于Linux内核开发的。但是Android与一般的Linux系统不同的是,它有着自己的一套独特的用户空间运行时,也就是我们通常说的应用程序框架。举个例子来说,以前很多基于Linux的嵌入式开发,就是移植一个Linux内核,然后再用Qt作为应用程序框架,这样一个系统就跑起来了。因此,将Qt应用程序框架替换为Android自己的应用程序框架,就得到了一个现代化的移动操作系统。 在Android应用程序框架中,包含了很多开源工程,例如浏览器用的内核WebKit、管理Wi-Fi网络的wap_supplicant、播放音乐视频的StageFright等,它们都是使用C/C++来写的。而且Android系统专用的用来渲染UI的SurfaceFlinger、用来播放声音的AudioFlinger等,也是用C/C++来写的。更不用提每一个应用程序都要使用到C库bionic、Dalvik虚拟机等了,它们都是用C/C++来写的。这些使用C/C++写的服务,实现了最基本的功能。这些最基本的功能被在Java层的提供的关键服务所使用,例如组件管理服务ActivityManagerService、应用程序安装服务PackageManagerService、网络连接服务ConnectivityService等。最后,Android再封装了一套基于Java语言的SDK给开发者去使用那些实现在Java层的系统服务。
从上面的调用过程就可以看出,Java只是位于Android最上面的一层编程接口,而没有这一层编程接口Android也是可以正常运行的。我们知道,Android除了提供SDK外,还提供有NDK。也就是说,我们完全可以不使用SDK,而是通过NDK提供的接口绕过Java Runtime Framework,直接将请求交给C/C++Runtime Framework处理。 至于Android系统使用的Linux内核,其实与传统的Linux内核并无多大区别,甚至可以看成是一样的。要说真的区别,就是有两点。一是Android在传统的Linux内核中以模块的形式加入了一些专用的驱动,例如日志驱动Logger、匿名共享内存驱动Ashmem、进程间通信驱动Binder。二是Android系统将在传统的Linux内核实现的硬件驱动程序划分成了两部分,一部分在内核实现,另一部分在用户空间实现,也就是我们常说的硬件抽象层HAL。Android系统之所以要这样划分,是出于商业考虑,而不是技术考虑。因为Linux内核使用的GPL许可协议,驱动全部放在内核实现就意味着需要全部开源代码,而用户空间使用的是Apaache License,可以不开源代码。通过这种方式,就可以保护厂家的商业利益,因为这些代码通常都会包含有硬件的相关参数。 CSDN:Android系统层次结构是怎样的?各个层之间关系是什么? 罗升阳:上面也提到了Android系统的层次,详细一点说,就是:Android = Linux Kernel + C/C++ Runtime Framework + Davik Virtual Machine + Java Runtime Framework + Java SDK。下面我们再以APK的开发、编译、安装和运行来说明这些层次之间的关系。 首先,我们是在PC上使用Android SDK提供的接口来开发APK,用的Java语言。开发完成之后,使用Java编译器将源代码编译成Java字节码,也就是带.class后缀的文件。接下来这些.class再被Android SDK提供的dx工具转化成Dex字节码,最后打包在APK里面的classes.dex文件中。 接着,APK文件在手机上安装时,Java Runtime Framework里面的PacakgeManagerService就会对该APK文件进行解析,并且通过Socket IPC通知C/C++ Runtime Framework里面的installd守护进程对APK里面的classes.dex文件进行优化,得到另外一个classes.odex文件。 APK安装完成之后,就可以运行了。我们以APK从桌面Launcher启动的过程为例说明它的运行过程。当我们从Launcher点击应用图标的时候,Launcher向Java Runtime Framework里面的ActivityManagerService发送一个启动应用的请求。ActivityManagerService又通过Socket IPC向C/C++ Runtime Framework里面的zygote守护进程请求创建一个应用程序进程。这个应用程序进程包含有一个Dalvik虚拟机。应用程序进程创建并且启动起来之后,就会通过它里面的Dalvik虚拟机加载前面提到的classes.odex文件。这样我们的应用程序就运行起来了。 APK的运行过程是依赖于Dalvik虚拟机的。我们可以将它看成是将classes.odex里面的字节码解释成本地机器指令执行。例如,我们在APK里面通过FileInputStream或者FileOutputStream打开一个文件的时候,Dalvik虚拟机就会找到C/C++ Runtime Framework里面的C库bionic提供的系统接口open,并且通过它来打开指定的文件。 我们再以应用程序界面的绘制和渲染过程来详细说明各个层次的关系。首先是应用程序通过SDK提供的UI类向Java Runtime Framework里面的WindowManagerService申请分配一块图形缓冲区。WindowManagerService又是通过Binder IPC向C/C++ Runtime Framework里面的SurfaceFlinger申请分配图形缓冲区的。图形缓冲区实际上不是由SurfaceFlinger分配的,而是由显示系统分配的,可能在显存里面,也有可能在GPU里面。这时候SurfaceFlinger就要通过HAL层次Gralloc模块向Kernel里面的显卡或者GPU驱动申请分配真正的图形缓冲区。HAL层可以看作是运行在C/C++ Runtime Framework中。 应用程序得通过上述方式得到绘制UI所需要的图形缓冲区之后,就开始绘制自己的UI了。假设应用程序使用的是硬件绘制方式,也就是通过C/C++ Runtime Framework里面的OpenGL来绘制。这时候SDK的UI类的与绘制相关的函数调用通过Dalvik虚拟机都转化成了C/C++ Runtime Framework里面的OpenGL操作。 应用程序UI绘制完成之后,结果就保存上述的图形缓冲区中。这时候如果要将该图形缓冲区渲染到手机屏幕上,那么还需要通过Binder IPC将该图形缓冲区发送给C/C++ Runtime Framework里面的SurfaceFlinger。SurfaceFlinger通过使用OpenGL或者HWComposer将所有请求要渲染到手机屏幕上的图形缓冲区合成之后,得到一个主图形缓冲区。最后这个图形缓冲区又会被SurfaceFlinger提交给Kernel的显卡驱动,并且在手机屏幕上进行显示。 上面描述的就是Android系统各个层次的调用关系。总的来说,应用程序运行在Dalvik虚拟机上,并且通过SDK使用Java Runtime Framework里面的服务,而Java Runtime Framework里面的服务又通过C/C++ Runtime Framework里面的服务来实现自己的功能,最后C/C++ Runtime Framework里面的服务又会在需要的时候请求Kernel里面的模块或者驱动来为自己服务。 CSDN:Andriod可以说是开源的代名词,一些开发者为了保护自己的成果进行加密,而另一些开发者为了学习,需要进行APK反编译,可以分享下您对加密和反编译的看法吗? 罗升阳:严格来说,Android系统是开放不是开源。Linux内核才是严格意义上的开源。只要是运行在Linux内核里面的代码,都可以要求作者将代码开源出来。但是运行在Android系统用户空间的代码,作者就不需要将它们开源出来了。这些代码包括厂商对Android官方源码的修改,以及自己增加的代码,还有第三方为之开发的APK代码等。这是由于Linux内核使用的是GPL许可协议,而Android系统的用户空间代码使用的Apache许可协议。 我觉得无论是开发者为了保护自己的成果而对APK进行加密,还是另一些开发者为了学习而反编译别人的APK,都是无可厚非的。当然前提是不要利用这些技术去做坏事,否则的话,就是违反法律的事情了。加密和反编译实际上是一种技术竞争关系。我们都知道,竞争其实是可以推进技术进步的,而技术进步的最终结果对用户是有好处的。 我在这两个讲《Android安全机制》和《APK防反编译技术》的PPT中,有描述过通过DEX和SO加壳、添加非法指令、隐藏敏感代码和伪APK加密技术等办法来保护代码的方法。然而,再厉害的保护技术,只要计算机知识牢固,并且有足够的耐心,再加上一些工具,例如apktool和ida,都是够破解的。当然,在别人破解了你现在的保护技术之后,你可以再发明另外的技术来保护自己的代码。这就是技术竞争,比的是各自的技术水平。 CSDN:深入理解框架层,需要具备哪些知识?对于开发应用具体有什么好处?而开发者在学习这一过程中应注意哪些问题? 罗升阳:从上面对Android系统的描述可以知道,要学入去学习Android系统的框架,需要具备的知识是不少的。
虽然应用开发者平时不用接触系统方面的东西,但是如果能够深入理解Android的框架层,好处是不言而喻的。
总之就是技多不压身,学到的东西都是自己的,以后靠这些技术赚到的钱也是自己的。但是前面讲到,要学入理解Android系统,需要具备的知识是很多的。基于这个原因,应用开发者最需要注意的问题就是不要被这个问题吓退。其实是没有人与生俱来就具备这些知识的,而且知识是无究无尽的,活到老就可以学到老。所以一定要坚持学习,一点一滴的积累,哪些不懂就补哪里。开始学慢一点没有关系,等积累到一定程度的时候,就会发现自己的学习能力呈加速度趋势。 CSDN:移动互联网如今发展得如火如荼,Android在其中占居着重要的角色,其发展众说纷纭, 你如何看待Android的未来? 罗升阳:Android的发展问题,无非就是与iOS相比,孰优孰劣的问题。目前在移动互联网上,还找不到第三个可以与Android和iOS抗衡的系统。Android与iOS相比,很多人无非就是觉得: 1. Android UI不够流畅; 刚开始的时候,Android UI与iOS相比,流畅性的确是差很多。一方面是因为Android手机参差不齐,有些在硬件配置上确实不如iOS。另一方面确实是Android系统自身的问题。但是我们看到自3.0以来,Android就一直在加强UI流畅性进行努力。Android在3.0在应用程序进程这一侧,允许使用硬件绘制UI。在4.1的时候,又通过Project Butter计划,极大地提高了UI的流畅性。到了L版本,又用ART代替了Dalvik,这意味着应用程序运行时执行的是本地机器指令,而不再是虚拟机机指令,性能将得到极大的提升。总之,目前在同等硬件配置下,Android的UI流畅性与iOS相比,差距是越来越小了。我们期待ART代替Dalvik之后,两者可以不相伯仲。 关于安全问题,iOS也有自身的安全问题,例如,每次iOS版本升级后,不也是有人很快就发布了越狱工具吗?同时我们也看到,Android在4.3版本,引进了SEAndroid,用来加强其安全性。SEAndroid是美国国家安全局(NSA)在SELinux的基础上专门为Android系统开发的,用来保证系统即使在被root的情况下,也能最大限度地保护用户手机的安全。另一方面我们也看到,由于Android系统是开放的,有很多第三方的安全公司,例如Bluebox,积极地帮忙发现漏洞,以便可以及时进行修复。 加密算法有一个Kerckhoffs原则:秘密寓于密钥。意思就是说一个密码系统的安全性,应该仅仅依靠“密钥没有泄漏”这个前提。即使整个系统落到了敌人的手里,敌人了整个系统的所有细节,但是如果敌人不知道密钥,你的传输还是安全的。无论是在战争还是和平时期,不能把保密的希望寄于系统/算法的保密性,因为机械的可以拆解,软件的可以看汇编。在这一点上,非公开算法和公开算法的区别就体现出来了:公开算法受全世界的密码学者研究,经受得考验;非公开算法只有除了作者外别人都不知道,可能有很好的攻击但是作者没有发现。我想由于Android系统是开源的,而iOS系统是闭源的,它们的安全性之间的比较可以类比于公开和非公开的加密算法安全性比较。 至于Android的耗电问题,很大程度是由应用程序引起的。由于某些原因,Google官方提供的统一推送服务不能在国内使用,导致了每一个需要网络推送的应用程序都自已在后台启用了一个服务,定时地检查服务器有没有新的通知。即使是手机已经休眠了,也会对其进行唤醒进行检查。这就造成了电量非常大的消耗。iOS有统一的推送服务,并且不允许应用自己设计一套推送服务,因此就可以保证电池的优化使用。为了一定程度上解决这个问题,Android在L版本提供了Job Scheduler服务,用来对齐应用对设备的唤醒,以达到优化电池使用的目的。 至于Android的兼容性,是由于Android系统的开放性造成的。各个厂商都可以将Android源码拿过来进行修改,并且跑在硬件配置各不相同的手机上,因此就造成在一个手机上运行得很好的程序,到了另外一个手机上就可能会出现问题。 归结来讲,Android的耗电问题和兼容性问题,很大程度都是由于Android的开放性导致的。然而,Android的开放性也正是它的优点所在。回想起上个世纪末期,苹果计算机与IBM兼容PC之争,我们就会发现,IBM兼容PC正是靠开放性打败了苹果计算机。当然,今时不同往日,今天依然闭源的iOS和开放的Android,两者除了在手机之外,在车载、穿戴式设备、智能家居方面,也都展开全面的竞争,鹿死谁人还不知。但是,我们现在看到的是,很多创业者,想要做自己的智能设备时,第一时间想到的肯定是使用Android系统。这说明Android系统有群众基础。我们期望众人拾柴火焰高,Android的发展越来越好。 |