本文转载地址:采访罗升阳:老罗Android之旅
编者按我们常说的智能手机实际上是在手机上增加了一个操作系统,所以大多数人都会像我一样问,这个操作系统和我们在计算机上接触更多的操作系统一样。道教云,看山是山,看山不是山,看山还是山。这三个领域也适用于以前的问题,你说不。
罗生阳出生于1984年,2007年毕业于浙江大学计算机系,获得学士学位,2010年毕业于上海交通大学计算机系,获得硕士学位。毕业后一直从事互联网软件开发,致力于移动平台的研究,尤其是对Android平台有深入的理解和研究。在国内知名IT技术社区CSDN发表了100多篇高质量的文章Android系统原创文章,博客专栏——老罗Android之旅》。积极与网友交流互动,深受大家喜爱,访问量一直居于前茅。同时,着有《Android系统源代码情景分析》一书。
:我现在正在做一款与手机游戏相关的产品Android玩家可以边玩游戏边录制直播。在中国,无论是传统的还是传统的PC游戏是互联网或移动互联网的巨大市场。在手机游戏超越页面游戏追赶终端游戏的今天,手机游戏录制和直播作为连接玩家和玩家、玩家和制造商的平台,近年来在国内外追逐。在国外,今年5月初,手机游戏被录制和共享社区KamcordA轮融资获得710万美元;5月中旬,又来了Google游戏直播公司花费10亿美元美元Twitch的消息。在中国,爱拍和ShareSDK还发布了手机游戏录制和共享相关产品。
除了其巨大的市场,手机游戏录制和直播产品也吸引了我。坦白说,在Android到目前为止,平台上还没有用户体验良好的手机游戏录制应用。目前Android市场上的手机游戏录制应用要么是性能问题,要么是稳定性或兼容性问题。包括在iOS平台做得很好Kamcord,在Android平台也表现平平。原因如下:
一是Android平台没有直接提供获取游戏画面和声音的接口。 二是Android平台的差异化使得很难在大多数手机上找到一个通用的技术解决方案。Root在手机上,虽然可以使用截屏接口获取游戏图片,但直接使用效率很低,难以满足帧率要求。另一个是通过阅读Frame Buffer获取游戏画面的方法是4.之后,就更行不通了。 此外,由于它是实时录制的,对视频编码的性能要求非常高。使用软编码基本上是不可行的,必须使用硬编码。但使用代码时,应考虑硬件的适应性,否则很容易产生稳定性和兼容性问题。
为了解决上述技术问题,需要使用非常底层Android例如,系统知识Android系统的UI渲染机制和硬编码知识。没有深刻的知识可以利用这些知识Android基础很难做到。因为我对Android系统有很深的研究,所以我觉得做这样的产品是一个有趣的挑战。
当然,除了手机游戏的录制和直播应用,我们还在研究和做一些基于它的事情Android毕竟,我对系统的可穿戴设备感兴趣的是Android系统,可穿戴设备也将是未来的方向之一。
:我接触电脑的时间比较晚。上大学之前,除了网吧,基本没接触过电脑。在真正接触电脑之前,大学选择了计算机专业。而且我很清楚,大一开学一个月左右,学校要在计算机文化的基础上进行计算机考试,其实就是考试Word和Excel的操作。考试前大约有两周时间让你有空的时候去机房练习。对于一个以前没有接触过计算机,打字也不敏捷的孩子来说,果然考试不及格。后来补考一次才通过。
因为学计算机专业,大一就要开始编程了。一开始学的是C语言,不像现在很多人一开始学的是C语言C#、Java、PHP这些先进易用的语言。后来逐渐学会了C 、Java和C#等等。刚开始学C语言很痛苦,龙其学指针、链表等知识。我记得大一上学期的国庆节,我花了几天时间啃链表。回想起来,一开始选择学习C语言是对的。因为无论你现在使用什么语言,如果你想彻底理解它背后的平台,你必然需要理解它的底层实现,这些底层实现基本上是不可分割的C/C 。换句话说,语言只是一种工具。理解软件实现原理的关键是理解软件背后的计算机系统,而C是最接近计算机系统的语言。因此,我强烈建议对软件开发感兴趣的学生,无论你现在和将来使用什么语言,你都必须学好C/C 。
接触Android该平台是研究生毕业后的工作。2011年初,正式接触写了一个简单的五子棋游戏。然而,在2010年下半年,我开始计划好好学习Android系统了。因为了解到Android系统是基于Linux内核实现了,所以2010年下半年,主要是补充Linux核心基础知识。事实上,激励我深入研究Android而不仅仅是系统Android应用程序的动机是当时在公司制作的软件应用程序框架。它是由公司的团队开发的,在学校没有使用MFC等待一般框架。当时,我对自己开发的应用程序框架非常感兴趣,但我们只是一个业务团队,通常只使用这个框架,没有机会深入研究。
2010年的时候,iOS已经很火了,Android也开始冒出尖尖的头。由于Android背后的靠山Google,而且它的源代码是开放的,所以要研究一下Android如何实现系统的应用程序框架?这样一来能跟上移动潮流,一来也能满足自己的好奇心。从此失控,正式步入Android系统的世界。
:那两年基本上把所有的业余时间都花在了学习上Android包括下班时间、周末、节假日等。因为这是第一次接触到这样的系统和底层知识,所以从一开始就弥补了Linux后来系统地学习内核知识Android系统的专用驱动、HAL在层和应用程序架构层等知识期间,遇到的困难可想而知。花了两年时间才完成Android系统研究的第一阶段任务之后,忍不住写了一篇文章《2012年的Android总结这段学习经历:梦想、学习、坚持、自信、冷静。正如文章所说,那两年的学习Android总而言之,经验是十个字:梦想、学习、坚持、自信、冷静。由于篇幅关系,这里就不一一展开了。不过,我最想分享还是关于坚持这一点。
坚持这两个字真的很容易说。即使是一件非常简单的事情,要求日复一日地坚持下去,恐怕很多人都做不到。例如,锻炼。我们不说每天,说每周拿出一到一个半小时锻炼,有多少人能坚持下去?这仍然需要时间来完成,不会遇到学习、工作、生活等挑战。所以我们说坚持就是胜利,很有道理。无论中间遇到什么样的困难和挑战,只要设定目标,就必须下定决心坚持下去。坚持成为一种习惯,离目标的实现不远。换句话说,如果你愿意坚持,你会发现:1.你的目标已经实现;2.你养成了良好的习惯。
经常听到有人说太难了,看/学/做不下去。事实上,没有什么是天生的。既然不是,学习过程一定要付出代价。在2010年下半年之前,我通常学习、工作和娱乐Windows第一次在平台上学习Linux内核看的是《Linux内核源代码场景分析 这本书。读过这本书的人都知道它基本上是一本天书。当时我对自己说,没关系。如果我不明白一遍,我会再看第二遍、第三遍和第四遍。最后的执行过程是,看完第一遍,心里只有一个谱。然后找一些相关的经典书继续读,比如《Linux内核设计与实现。看完了《Linux内核设计与实现《Linux内核源代码场景分析。现在我发现有些地方我现在明白了,但还有其他地方我不明白。于是,继续看《Linux设备驱动程序和深入理解Linux内核等书。每次觉得有必要的时候,都要看一遍《Linux内核源代码场景分析。经过三四次这样的折腾,终于可以愉快地理解了《Linux内核源代码场景分析。
当然,除了毅力,我们还应该知道如何坚持。马丁·路德·金
的一句话:
If you can’t fly, then run; if you can’t run, then walk; if you can’t walk, then crawl, but whatever you do, you have to keep moving forward。
我认为关键是最后三个词keep moving forward”。在坚持的过程中,你应该让自己觉得自己一直在keep moving forward这样才会有坚持下去的动力。换句话说,即使是一点点进步,也要让自己在坚持的过程中看到事情再进一步。以阅读为例。平均每天看20页,一年看7300页。还有5840页,相当于10本书。读完10本书,你可以学到很多东西。在这个过程中,每天读20页书就是把你推向前一步。有些人可能认为每天读20页书太难了。是的,一开始可能有点难。然而,当你坚持一段时间时,你会发现你知道的知识越来越多,阅读的速度也会加快。不要说一天20页,一天50页不是问题。
:刚开始只想通过博客记录自己的学习。Android没有写书的计划。随着博客人气的上升,出版社不断出现辑发出出书的邀请。开始的时候,基本上还是拒绝的。再到后来,也有不少网友建议把博客整理一下成书出版。在出版社和网友的多次建议下,也考虑到有些读者可能更喜欢阅读纸质书,最终就决定把博客的文章整理成书出版了。
第一次写书,怀着的是诚惶诚恐的心情,担心能力有限,误人子弟。书与博客不一样,出书包含有出版社、渠道和销售等成本,因此读者是不可能免费得到的。既然读者要付出钱来购买你的书,那你写书的时候就得负起责任,例如要保证内容的系统性、完整性和正确性,还有文字表达的通顺性,甚至还不能出现错别字。这与在网上写博客有很大的区别。写博客可以比较随意一点,漏掉的内容可以以后再补,错误字也可以马上就修改过来。
基于面这些原因,写书过程经历的困难是可想而知的。决定写书之后,一开始并没有急着去写,而是将计划纲入书里面的内容都先发表到博客上,也就是我在2011年12月前发表的文章。主要是考虑到先将内容发表出来,让读者看到之后可以帮忙发现BUG以及提建议,这样可以帮助提高书的质量。整理博客不是简单的拷贝粘贴,比我想象中要困难多了。回过头来再看自己发表过的文字,百分之七八十都要重新表达。而且有些章节,要系统地描述清楚,单靠博客上的文章是远远不够的。例如,在写Binder那一章时,原以为在博客写的一系列文章已经够完备了,但是发现只是写了一半不到。然后就拼命地一边整理已有的内容,并且一边补新的内容。
在时间上,从开始整理到出版的半年时间里,除了工作基本就是扑在写书上了,而且利用的都是工作之余的时间。没有周末,没有节假日,工作日也是经常熬夜到两三四点。对程序员来说,写文字其实比写代码要累多了,这就是为什么程序员都不喜欢给自己的代码写文档写注释的原因。期间是想过要放弃的,但是已经跟出版社签定了合同,怎么都坚持下去啊。就这样一路走来,从博客文章整理得到初稿,又经过三遍逐行逐行的校对,终于完成了三大篇十六章830页近160万字的著作。说实话,当时要是再让我看第四遍的时候,感觉都要吐了。
Android版本更新的确是比较快,不过目前是没有出第二版的计划了。主要是因为我写的内容都是很基础的东西,例如HAL、Binder IPC、Ashmem、Logger,以及四大组件Activity、Service、Broadcast Receiver和Content Provider的实现原理,它们在后来的版本中仍然是保持性当初的设计思想和运行原理的。我更希望的是,读者看了我的书之后,能够自己去分析Android系统的源码,这样以后Android版本更新得再快也不怕了。
至于新书,以前是有计划的。完成了《Android系统源代码情景分析》一书之后,我又陆续在博客了发表了UI架构、UI渲染、窗口管理、Dalvik虚拟机、编译系统、SEAnroid安全机制等一系列的文章。这些内容加起来也可以有《Android系统源代码情景分析》这本书那么厚了。不过写书是费时费力的事情,而且产出投入比也不高,再加我也不是专职的图书作家,所以现在也不打算出新书了。但是博客是一定会坚持写下去的,希望读者可以持续关注,并且可以在博客上与我交流。
:实际上,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层的系统服务。
也就是说:Android系统=Linux内核+Android用户空间运行时+ Android SDK,而Android用户空间运行时=C/C++ Runtime Framework + Java Runtime Framework。很多情况下,我们调用Android SDK提供的一个API时,这个API调用会交给Java Runtime Framework处理,而Java Runtime Framework又继续将这个API调用交给C/C++ Runtime Framework处理,最后C/C++ Runtime Framework又有可能接着将这个API调用交给Linux内核来处理。
从上面的调用过程就可以看出,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,可以不开源代码。通过这种方式,就可以保护厂家的商业利益,因为这些代码通常都会包含有硬件的相关参数。
:上面也提到了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里面的模块或者驱动来为自己服务。
:严格来说,Android系统是开放不是开源。Linux内核才是严格意义上的开源。只要是运行在Linux内核里面的代码,都可以要求作者将代码开源出来。但是运行在Android系统用户空间的代码,作者就不需要将它们开源出来了。这些代码包括厂商对Android官方源码的修改,以及自己增加的代码,还有第三方为之开发的APK代码等。这是由于Linux内核使用的是GPL许可协议,而Android系统的用户空间代码使用的Apache许可协议。
我觉得无论是开发者为了保护自己的成果而对APK进行加密,还是另一些开发者为了学习而反编译别人的APK,都是无可厚非的。当然前提是不要利用这些技术去做坏事,否则的话,就是违反法律的事情了。加密和反编译实际上是一种技术竞争关系。我们都知道,竞争其实是可以推进技术进步的,而技术进步的最终结果对用户是有好处的。
我在这两个讲《Android安全机制》和《APK防反编译技术》的PPT中,有描述过通过DEX和SO加壳、添加非法指令、隐藏敏感代码和伪APK加密技术等办法来保护代码的方法。然而,再厉害的保护技术,只要计算机知识牢固,并且有足够的耐心,再加上一些工具,例如apktool和ida,都是够破解的。当然,在别人破解了你现在的保护技术之后,你可以再发明另外的技术来保护自己的代码。这就是技术竞争,比的是各自的技术水平。
:从上面对Android系统的描述可以知道,要学入去学习Android系统的框架,需要具备的知识是不少的。
从语言层面来说,需要掌握C、C++、Java,甚至还有汇编。
从系统层面来说,需要有Linux内核基础,包括进程管理、内存管理、文件系统等,还需要掌握Android的HAL、C/C++ Runtime Framework、Java Runtime Framework和Davivk等。
虽然应用开发者平时不用接触系统方面的东西,但是如果能够深入理解Android的框架层,好处是不言而喻的。
首先,可以提高能力和拓宽眼界。因为要看得懂Android系统的代码,要求了解很多知识。要了解这么多的知识,又需要不断地去学习。在学习的过程中,能力和眼界就会自然得到提高和拓宽。
其次,可以正确地使用SDK接口。学习SDK接口,我们一般是通过阅读SDK文档。但是这些SDK文档只是告诉你它们是怎么用的,没有告诉你它们是怎么实现的。如果我们既知道一个SDK接口是怎么用的,又知道它是怎么实现的,那么用起来肯定会得心应用很多。而且在使用出错的时候,也能迅速地通过检查它的实现代码来定位原因。
再者,可以有效地解决BUG。当程序运行出错的时候,系统除了会输出异常信息或者Crash信息之外,通常还有伴随着一些错误日志输出。往往这些系统输出的错误日志包含很丰富的信息,告诉到底是哪些地方出错了。但是这些错误日志是由系统输出的,它们的含义以及输出条件都是由系统定义的。这时候如果要理解到底是什么地方出错了,那就得对系统有一定的理解,甚至需要找到输出这些日志的系统代码来阅读一下。
总之就是技多不压身,学到的东西都是自己的,以后靠这些技术赚到的钱也是自己的。但是前面讲到,要学入理解Android系统,需要具备的知识是很多的。基于这个原因,应用开发者最需要注意的问题就是不要被这个问题吓退。其实是没有人与生俱来就具备这些知识的,而且知识是无究无尽的,活到老就可以学到老。所以一定要坚持学习,一点一滴的积累,哪些不懂就补哪里。开始学慢一点没有关系,等积累到一定程度的时候,就会发现自己的学习能力呈加速度趋势。
:Android的发展问题,无非就是与iOS相比,孰优孰劣的问题。目前在移动互联网上,还找不到第三个可以与Android和iOS抗衡的系统。Android与iOS相比,很多人无非就是觉得:
1. 2. 3. 4.
刚开始的时候,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的发展越来越好。
:要在激烈的移动互联网环境中提升自己的核心竞争力,关键还是要提到自己的技术水平,最佳的途经就是持续的不断学习。学习既要有广度,又要有深度。自己感兴趣的知识,一定要深入去研究。其它相关的知识,也要尝试去有一定的了解。
关于学习这个话题,有些人觉得现在用不到的东西就没有必要去学习,否则就太浪费时间了。其实,很多东西等到要用到的时候再去学,就太迟了。要知道,我们通过学习用到的东西,虽然不会直接反应在我们现在工作的内容上,但是也会潜默移化地响应着我们思考方式,把我们往好的方向推动。还有的就是,我们学的所有东西都不会白白浪费的,总有一天都会派上用场的,特别是在当今十年河东十年河西的科技时代。十年前,火的是传统互联网;十年后,轮到移动互联网上场;再过五年或者十年呢?谁都不知道会怎么样,但是只要我们有技术在手,就能积极拥抱变化。毕竟从技术层面讲,无论时代怎么变化,核心的东西都相通的。
要推荐的书,我在《那两年炼就的Android内功修养》这篇文章中有提到,这里再列一下出来:
- 语言类:
《深度探索C++对象模型》,对应的英文版是《Inside C+++ Object Model》
- 程序编译、链接、加载类:
《链接器和加载器》,对应的英文版是《Linker and Loader》
《程序员的自我修养:链接、装载和库》
- 操作系统类:
《Linux内核设计与实现》,对应的英文版是《Linux Kernel Development》
《深入理解Linux内核》,对应的英文版是《Understanding the Linux Kernel》
《深入Linux内核架构》,对应的英文版是《Professional Linux Kernel Architecture》
《Linux内核源代码情景分析》
- 网络类:
《Linux网络体系结构:Linux内核中网络协议的设计与实现》,对应的英文版是《The Linux Networking Architecture: Design and Implementation of Network Protocols in the Linux Kernel》
《深入理解LINUX网络技术内幕》,对应的英文版是《 Understanding Linux Network Internals》
- 设备驱动类:
《Linux设备驱动程序》,对应的英文版是《Linux Device Drivers》
《精通Linux设备驱动程序开发》,对应的英文版是《Essential Linux Device Drivers》
- 虚拟机类:
《Java SE 7虚拟机规范》
《深入Java虚拟机》,对应的英文版是《Inside the Java Virtual Machine》
《Oracle JRockit: The Definitive Guide》
- 嵌入式类:
《嵌入式Linux开发》,对应的英文版是《Embedded Linux Primer》
《构建嵌入式Linux系统》,对应的英文版是《Building Embedded Linux Systems》
- ARM体系架构类:
《ARM嵌入式系统开发:软件设计与优化》,对应的英文版是《ARM System Developer’s Guide: Designing and Optimizing System Software》
- 综合类:
《深入理解计算机系统》,对应的英文版是《Computer Systems: A Programmer’s Perspective》
同时,我自己也是处于不断的学习中,平时也会看其它比较多的书,大家有兴趣的话,可以关注我的新浪微博(@罗升阳
),上面有不定时的推荐。
:当初选择写博客,是写给自己看的,当笔记用。否则如果什么都不写的话,研究过的东西很快就忘记了。直到现在,在需要的时候,我都会去翻自己的博客。随着博客读者越来越多,博客就不再是给自己当笔记用了,还是一个用来学习交流分享知识,以及结识志同道合的朋友的场所。
不过,我觉得最重要的是,通过发表博客文章,可以让对我Android的研究更加严谨、更加详细、更加系统。因为每天这么多读者浏览你的文章,你就必须要保证文章的质量,否则的话就会误人子弟,也会毁了自己的名声。为了写出有质量的文章,就必须要严谨、详细和系统地去研究Android系统的代码。因此,写博客和研究Android是一个相互促进的过程。
:在写博客之前,其实是比较少接触CSDN。2011年6月决定要通过博客来记录自己研究Android的历程时,也尝试过找其它的博客网站来写文章。最后发现CSDN文章贴的代码显示格式用户体验挺好的。于是就决定使用CSDN博客了。
CSDN对学习和工作的影响,最主要的就是它让我用严谨、详细、系统的方法去研究Android,从而也使得我对Android系统的理解更加深入。
对CSDN的建议,就是希望CSDN可以加强稳定性,以前时不时都会出现访问不了的情况,不过最近半年情况好像是好一些了。另外一个是加强对移动端的用户体验。我看到最近CSDN增加了对移动端的支持,不过在浏览个人博客时,看不到博主的相关信息,例如浏览量、积分、排名和评论等。有时候想看看有没有新的评论需要回复,看不到就麻烦的,无法与读者进行交流,而且又不能切换回PC端模式。
读采访罗升阳有感
在看完罗升阳前辈的采访后,我感受到了强大的学习能力和对android以及整个互联网知识的了解程度! 我发自内心的崇拜罗升阳前辈
所以我转载写下这边博文 以资鼓励自己 如果迷茫了 就来看一下! 从中获取力量 强大自己。 再次感谢前辈!