在windows下想流畅阅读Android源代码是比较费劲的事情,不论是起虚拟机,还是怎么着。
一个比较傻但是还是比较有效的方式,是找个Linux的机器(不论是在本机还是在其他机器上),按步骤下载并编译好源代码,并按照配置eclipse方式,把.classpath拷贝到源码的根目录下。
然后,把它放到windows可访问的存储介质上,如果在本机可以放到windows下的分区内,或者是拷贝到移动硬盘中。这样,不论在windows还是在Linux下,都可以用eclipse建立工程,方便查看了。
为什么那么简单的解决策略一直懒得去想,FML。
Tags:Android Posted in 技术

一幅图,广义一些,说的是产品设计;具体一点,想表达的是手机软件产品的设计思路。
很多时候,产品设计强调的三元素,是价值,用户需求和条件约束,换算成关系便如上图示。
做每个产品,都必须要有一些核心的东西,这些核心的东西,是用户会使用产品的理由,也是抵御竞争对手的最强有力的武器。但每一点点的价值,都来之不易,都需要充分利用已有的资源,星星点点的积累。有句话说,心比天高命比纸薄,如果你想提供的核心价值很宏伟,但有的资源很不给力,那所有想法,都成了水中月镜中花。在资源满足的情况下,才能把核心价值折算成为一个个功能点,根据价值高低和资源的可利用度综合评估,最终决定提供什么不提供什么。
产品的另一面,是用户。用户期望完成通过产品满足点什么,或者我们期望产品能让用户满足点什么。当然,用户使用产品是有环境的,用户需求和完成目标的过程,只有放到具体的环境里面去设身处地的考量,才能体现其价值。从而,从用户目标出发,在具体环境找考量,也能够得到一些能够实现这些目标的功能及其设计。
综合起来,从价值和用户目标共同考量,建立标准进行评估,就可以得到需要的功能,如何设计,以及,如何安排这一步和下一步开发。
Activity间数据传输
当对Android有一些了解后,不难发现,Android程序UI框架接近于Web页面的概念。每一个用于呈现页面的组件,Activity,都是彼此独立的,它们通过系统核心来调度整合,彼此之间的通过Intent机制来串联。
每一种架构都会有其利弊,Android当然也不能超然脱俗。由于Activity之间的松耦合关系,使得其复用能力特别的出色,Mash-Up方式可以有效的提高开发效率。但另一方面,由于Activity过于的独立,它们之间的数据共享,成为一个麻烦的事情。
基于消息的传输
最标准的Activity之间的数据传输,就是通过Intent的Extra对象。比如,你在A这个Activity上拿到一坨用户输入的文本信息,兴高采烈的想把它放到B这个Activity上展示并发送,一个很可行的方式,是通过Intent的putExtra接口,把用户输入的那些字符信息,按照key/value的形式放进Intent,传输到B这个Activity上。
如上图示,从A到B的传输,看上去是一个直连,但其实,Intent都是要经由系统核心层去分析调度的,这个操作,跨越了进程边界,自然而然,其中的数据,就是需要序列化和反序列化的,而不可以仅通过一个指针就倒腾过去了。 »继续阅读
Tags:Android,数据传输,移动,组件 Posted in 技术
资源文件
作为一枚coder,做界面,很多时候都是一场梦魇。很多时候,我们会感觉对于底层逻辑实现的很有把握性,哪怕需求一直在变,也可以通过不断的重构一直跟进,一切尽在掌握。但遭遇界面,往往就不再如此,它的好坏总是和审美、体验之类的词汇扯在一起,在凤姐芙蓉出没的年头,谈审美成为一件恐怖的事情。你可能会被要求不停的改代码,就为了移动一个像素,调整一枚按钮,琐碎而无聊。
为了改变这样的状况,挽救coder们于水生活热之中,很多开发平台,都采用了类似于资源文件的解决方案。此类方案的基本思想是,将界面的实现与底层逻辑的实现完全剥离开来,用资源文件这样的东西来描述界面。资源文件的描述语言,往往是结构化很强,比如Html,Xml(及其变形体)之类的。于开发语言相比,此类语言逻辑性较弱但结构更好可读性更强更容易理解,并对自动化工具非常友好,可以于界面的拖拽配置结合的更加完美。这样的剥离,可以是的底层逻辑和上层界面独立变化,甚至不同的人员开发(这一点在web开发上表现的应该很明显…),两者之间的耦合性非常的小,coder们的负担,陡然减少(好吧,一个很挫的资源架构也会额外增加开发人员的负担,Symbian同学,请不要对号入座…)。
结构和格式
Android的资源文件,是由目录结构,Xml格式的文件,和纯数据文件构成。从格式上来看,无疑,学习门槛非常低。Xml作为coder们的瑞士军刀,哪怕使不习惯,弄得清楚并会用至少是没有问题。从配套的工具来看,Android的ADT,提供了一套可视化的配置工具,说不上特别好用,但至少是差强人意能凑合着用,比不上iPhone的,调戏Symbian还是没有问题的[强档广告首播:有道词典 for iPhone新版火热上线,增加了超强单词本功能,特有的触电式颤抖单词切换功能,让你欲罢不能,持有相关设备的童鞋不要犹豫,一拥而上吧…]。 »继续阅读
Tags:Android,UI框架,源码剖析,移动 Posted in 技术
界面构造
UI界面,对于每个应用而言,是它与用户进行交互的门脸。好的门脸,不只是是要亮丽可人,最好还能秀色可餐过目不忘,甚至还应该有涵养有气质,彬彬有理温柔耐心。
对于开发者来说,锻造这样的面容,不但需要高超的技艺,也需要有称手的工具和对得起党的料子。俗话说,朽木不可雕也,芙蓉不是一日炼成的,不是什么平台都能叫特能书。有套好用的UI框架,对于开发者而言,真有如沙漠中的甘露,而要是撞见了杯具的UI套件,整个界面开发就有如梦魇了。
Android的UI框架,最核心的,是资源和Layout体系,然后,通过完善的控件库,简明的接口设计,进一步帮助开发者,能够最快的搭建自己需要界面(听到这里,Symbian同学开始钻土…)。
UI控件
做UI,有时候就像搭积木,在Android中,这个最原子的积木块,就是View。所有其他的UI元素,都是派生于此类的子孙类们。

又从SDK中偷来张图,用来描述Android的UI控件结构,在每一个window下,这都是一个标准而完整的树结构。View有一个子类ViewGroup,它相当于一个容器类或者是复合控件,所有派生与ViewGroup的子类在这颗UI树中都可以承担着父节点的职责,而另一些绕过ViewGroup从View直通下来的,就只能蜷局在叶节点的范畴内了。
之所有说这是一个很标准的控件树,是因为父控件对子控件有绝对的掌控权,每个子控件的占地面积和位置,都是基于父控件来分配的,它能够接受和处理的事件,也是父控件派发下去的。这样的结构,被很多平台和框架广泛的认可,和传统的win开发和杯具的Symbian相比,虽然因为事件传播途径变长了,很多操作的效率变低了,但整个结构更有层次性,每个控件只需要多其父控件负责指挥子控件就好,职责明确,逻辑简单,利于开发和设计。
谈及任何平台的控件,都有一些不可避免的主题,比如,每个控件如何标识,如何设定大小和位置,如何接受和处理事件,如何绘制,诸如此类。 »继续阅读
Tags:Android,UI框架,源码剖析,移动 Posted in 技术
任务、进程和线程
关于Android中的组件和应用,之前涉及,大都是静态的概念。而当一个应用运行起来,就难免会需要关心进程、线程这样的概念。在Android中,组件的动态运行,有一个最与众不同的概念,就是Task,翻译成任务,应该还是比较顺理成章的。
Task的介入,最主要的作用,是将组件之间的连接,从进程概念的细节中剥离出来,可以以一种不同模型的东西进行配置,在很多时候,能够简化上层开发人员的理解难度,帮助大家更好的进行开发和配置。
任务
在SDK中关于Task(guide/topics/fundamentals.html#acttask),有一个很好的比方,说,Task就相当于应用(application)的概念。在开发人员眼中,开发一个Android程序,是做一个个独门独户的组件,但对于一般用户而言,它们感知到的,只是一个运行起来的整体应用,这个整体背后,就是Task。
Task,简单的说,就是一组以栈的模式聚集在一起的Activity组件集合。它们有潜在的前后驱关联,新加入的Activity组件,位于栈顶,并仅有在栈顶的Activity,才会有机会与用户进行交互。而当栈顶的Activity完成使命退出的时候,Task会将其退栈,并让下一个将跑到栈顶的Activity来于用户面对面,直至栈中再无更多Activity,Task结束。
| 事件 |
Task栈(粗体为栈顶组件) |
| 点开Email应用,进入收件箱(Activity A) |
A |
| 选中一封邮件,点击查看详情(Activity B) |
AB |
| 点击回复,开始写新邮件(Activity C) |
ABC |
| 写了几行字,点击选择联系人,进入选择联系人界面(Activity D) |
ABCD |
| 选择好了联系人,继续写邮件 |
ABC |
| 写好邮件,发送完成,回到原始邮件 |
AB |
| 点击返回,回到收件箱 |
A |
| 退出Email程序 |
null |
如上表所示,是一个实例。从用户从进入邮箱开始,到回复完成,退出应用整个过程的Task栈变化。这是一个标准的栈模式,对于大部分的状况,这样的Task模型,足以应付,但是,涉及到实际的性能、开销等问题,就会变得残酷许多。比如,启动一个浏览器,在Android中是一个比较沉重的过程,它需要做很多初始化的工作,并且会有不小的内存开销。但与此同时,用浏览器打开一些内容,又是一般应用都会有的一个需求。设想一下,如果同时有十个运行着的应用(就会对应着是多个Task),都需要启动浏览器,这将是一个多么残酷的场面,十个Task栈都堆积着很雷同的浏览器Activity,是多么华丽的一种浪费啊。于是你会有这样一种设想,浏览器Activity,可不可以作为一个单独的Task而存在,不管是来自那个Task的请求,浏览器的Task,都不会归并过去。这样,虽然浏览器Activity本身需要维系的状态更多了,但整体的开销将大大的减少,这种舍小家为大家的行为,还是很值得歌颂的。 »继续阅读
Tags:Android,源码剖析,移动,进程模型 Posted in 技术
Intent解析
基于组件的架构体系,除了有定义良好的组件,如何把这些组件组装在一起,也是一门艺术。在Android中,Intent(貌似通常译作:意图…),就是连接各组件的桥梁。
前段时间看同事们做Symbian平台的网易掌上邮(真的是做的用心,NB的一米,热情欢迎所有163邮箱的S60v3用户,猛点击之…),有个功能是为邮件添加附件,比如你想要通过邮件发送一副图片泡mm,可能需要有个很直观的方式从本地选一副珍藏美图,抑或是拿相机来个完美自拍。在Symbian中,这样的功能,都需要你用底层的API,自己一点点写。为了让选图片体验更好,可能需要做一个类似于图片浏览器之类的东西,为了把拍照做的更为顺畅,甚至需要实现从聚焦到调节亮度之类一整套的相机功能。
而其实呢,用户的手机中可能本身就装了其他的专业图片浏览器、相机等应用,这些应用已经非常出色好用,而用户也已然能很纯属使用它们,如果能进行调用,对邮箱的开发者和用户而言,都会是个更好的选择。但在Symbian这样残败的系统里,应用和应用之间的结合能力奇弱无比,想复用,基本比登天还难,作为开发者,只能忍住一次又一次的恶心,为了用户,做这些重复造轮子吃力不讨好的附加工作。
还好还好,在Android中,一切变得美好多了,它将开发者从接口和对象的细节中解救出来,让我们有更多精力投入到核心功能的开发中去。在Android中,如果你需要选个图拍个片,只需要构造一个描述你此项意愿的Intent,发送出去,系统会帮你选择一个能够处理该项业务的组件来满足你的需求,而不再需要纠结在具体的接口和实现上,Perfect World,便应如此。
Intent构成
Intent被译作意图,其实还是很能传神的,Intent期望做到的,就是把实现者和调用者完全解耦,调用者专心将以意图描述清晰,发送出去,就可以梦想成真,达到目的。
当然,这么说太虚了,庖丁解牛,什么东西切开来看看,也许就清晰了。Intent(reference/android/content/Intent.html),在Android中表现成一个类,发起一个意图,你需要构造这样一个对象,并为下列几项中的一些进行赋值:
- Action。当日常生活中,描述一个意愿或愿望的时候,总是有一个动词在其中。比如:我想做三个俯卧撑;我要看一部x片;我要写一部血泪史,之类云云。在Intent中,Action就是描述看、做、写等动作的,当你指明了一个Action,执行者就会依照这个动作的指示,接受相关输入,表现对应行为,产生符合的输出。在Intent类中,定义了一批量的动作,比如ACTION_VIEW,ACTION_PICK,之类的,基本涵盖了常用动作,整一个降龙十八掌全集。当然,你也可以与时俱进,创造新的动作,比如lou这样的。与系统预定义的相比,这些自定义动作的流通范围很是有限,除非做了非常NB的应用,大家都需要follow你,否则通常都是应用内部流通。
- Data。当然,光有动作还是不够的,还需要有更确切的对象信息。比如,同样是泡这个动作,但泡咖啡,和泡妞,就差之千里了。Data的描述,在Android中,表现成为一个URI。用在内部通信中,可能描述是Content Provider用的形如content://xxxx这样的东东,抑或是外部的一个形如tel://xxxx这样的链接。总而言之,是能够清楚准确的描述一个数据地址的uri。
- Type。说了Data,就必须要提Type,很多时候,会有人误解,觉着Data和Type的差别,就犹如泡妞和泡马子之间的差别一样,微乎其微。但其实不然,Type信息,是用MIME来表示的,比如text/plain,这样的东西。说到这里,两者差别就很清晰了,Data就是门牌号,指明了具体的位置,具体问题具体分析,而type,则是强调物以类聚,解决一批量的问题。实际的例子是这样的,比如,从某个应用拨打一个电话,会发起的是action为ACTION_DIAL且data为tel:xxx这样的Intent,对应的人类语言就是拨打xxx的电话,很具象。而如果使用type,就宽泛了许多,比如浏览器收到一个未知的MIME类型的数据(比如一个视频…),就会放出这样的Intent,求系统的其他应用来帮助,表达成自然语言应该就是:查看pdf类文档,这样的。
- Category。通过Action,配合Data或Type,很多时候可以准确的表达出一个完整的意图了,但也会有些时候,还需要加一些约束在里面才能够更精准。比如,如果你虽然很喜欢做俯卧撑,但一次做三个还只是在特殊的时候才会发生,那么你可能表达说:每次吃撑了的时候,我都想做三个俯卧撑。吃撑了,这就对应着Intent的Category的范畴,它给所发生的意图附加一个约束。在Android中,一个实例是,所有应用主Activity(就是单独启动时候,第一个运行的那个Activity…),都需要能够接受一个Category为CATEGORY_LAUNCHER,Action为ACTION_Main的意图。
- Component。在此之前,我们企图用Action,Data/Type,Category去描述一个意图,这是Android推荐,并期望大家在大多数时候使用的,这样模式在Android中称做Implicit Intents,通过这种模式,提供一种灵活可扩展的模式,给用户和第三方应用一个选择权。比如,还是一个邮箱软件,他大部分功能都好,就是选择图片的功能做的很土,怎么办?如果它采用的是Implicit Intents,那么它就是一个开放的体系了,手机中没有其他图片选择程序的话,可以继续使用邮箱默认的,如果有,你可以任意选择来替代原有模块完整这功能,一切都自然而然。但这种模式,也不是没有成本,需要付出的是一些性能上的开销,因为毕竟有一个检索过程。于是,Android提供了另一种模式,叫做Explicit Intents,就需要Component的帮助了。Component就是类名,完整的,形如com.xxxxx.xxxx,一旦指明了,一切都清晰了,找的到这个类(当然会是一个特定的子类…),成功,反之,失败。这个好处,自然是速度,适合在你明确知道这就是一个内部模块的时候,使用它。
- Extras。通过上面的这些项,识别问题,基本完美解决了,剩下一个重要的问题,就是传参。Extras是用来做这个事情的,它是一个Bundle类的对象,有一组可序列化的key/value对组成。每一个Action,都会有与之对应的key和value类型约定,发起Intent的时候,需要按照要求把Data不能表示的额外参数放入Extras中(当然,如果不需要额外附加参数,就算了…),否则执行者拿到的时候会抓狂的。
- Flags。能识别,有输入,整个Intent基本就完整了,但还有一些附件的指令,需要放在Flags中带过去。顾名思义,Flags是一个整形数,有一些列的标志位构成,这些标志,是用来指明运行模式的。比如,你期望这个意图的执行者,和你运行在两个完全不同的任务中(或说进程也无妨吧…),就需要设置FLAG_ACTIVITY_NEW_TASK的标志位。
有了上述这些,一个Intent的形象就跃然纸上了,如此丰富的内容,决定了它比传统的模式,都来得强大。
»继续阅读
Tags:Android,源码剖析,移动,组件 Posted in 技术
Android组件
横看成岭侧成峰,远近高低各不同。 — 《题西林壁》
组件(Component),在谈及所谓架构和重用的时候,是一个重要的事情。很多时候都会说基于组件的软件架构,指的是期望把程序做乐高似的,有一堆接口标准封装完整的组件放在哪里,想用的时候取上几个一搭配,整个程序就构建完成了。
在开篇的时候就在说,Android是一个为组件化而搭建的平台,它引入所谓Mash-Up的概念,这使得你在应用的最上层,想做的不组件化都是很困难的一件事情(底层逻辑,好吧,管不了…)。具体说来,Android有四大组件四喜丸子:Activity、Service、Broadcast Receiver、Content Provider。
Activity
做一个完整的Android程序,不想用到Activity,真的是比较困难的一件事情,除非是想做绿叶想疯了。因为Activity是Android程序与用户交互的窗口,在我看来,从这个层面的视角来看,Android的Activity特像网站的页面。
首先,一个网站,如果一张页面都没有,那…,真是一颗奇葩。而一张页面往往都有个独立的主题和功能点,比如登录页面,注册页面,管理页面,如是。
在每个页面里面,会放一些链接,已实现功能点的串联,有的链接点了,刷,跑到同一站点的另一个页面去了;有的链接点了,啾,可能跳到其他网站的页面去;还有的链接点了,恩…,这次没跑,但当前页面的样子可能有所变化了。这些模式,和Activity给人的感觉很像,只不过实现策略不同罢了,毕竟Android这套架构的核心思想,本身就来自源于Web的Mash-Up概念,视为页面的客户端化,也未尝不可。
Activity,在四大组件中,无疑是最复杂的,这年头,一样东西和界面挂上了勾,都简化不了,想一想,独立做一个应用有多少时间沦落在了界面上,就能琢磨清楚了。从视觉效果来看,一个Activity占据当前的窗口,响应所有窗口事件,具备有控件,菜单等界面元素。从内部逻辑来看,Activity需要为了保持各个界面状态,需要做很多持久化的事情,还需要妥善管理生命周期,和一些转跳逻辑。对于开发者而言,就需要派生一个Activity的子类,然后埋头苦干上述事情。对于Activity的更多细节,先可以参见:reference/android/app/Activity.html。后续,会献上更为详尽的剖析。 »继续阅读
Tags:Android,移动,组件 Posted in 技术
Android架构和特征
千呼万唤始出来,犹抱琵琶半遮。 — 《琵琶行》
虽贵为富二代,但Android要是没任何可圈点的地方,开不过70迈,在玲琅满目的手机平台竞争中,充其量也就做几个俯卧撑打一桶酱油,然后被落的远远的。说到底,出来混,靠的还是技术。
架构

从SDK文档中,偷来一幅Android平台的架构图,如上。在整个架构最底层红彤彤的部分,是Linux Kernel在移动平台的一个移植,它隐藏了硬件、网络等相关的细节,为上层提供了一个相对纯洁的统一接口。除非要做的是Android到不同设备的移植工作,否则对于大部分普通开发者而言,基本上是远观而不必亵玩的。Google一直强调,Android的底层实现异常NB,可移植性超强,暂没有功夫研读,实属遗憾。
靠上一层,是一些核心的和扩展的类库,它们都是原生的C++实现。在这一层,你可以看到很多熟悉的面孔,一如SQLite、WebKit、OpenGL,开源的力量与贡献由此可见。如果,该层类库需要被上层函数调用,就必须要通过JNI的导出相应的接口函数,否则就只能在层次内部自个把玩。
也是在这一层次上,还有为上层Java程序服务的运行时。Dalvik虚拟机,是Android的Java虚拟机,之所以不采用J2ME的虚拟机,一方面是因为J2ME的设计是为了低端机器而优化,而Dalvik则是为了高端一些的机器进行优化,提供更好的性能。另一方面,从商业角度来看,必须绕开J2ME虚拟机,Android才能彻底解放,想怎么开源就怎么开源,不再需要考虑License的问题。
再往上,终于有Java出没了。首先是框架层,这里包含所有开发所用的SDK类库,另外还有一些未公开接口的类库和实现,它们是整个Android平台核心机制的体现。
而在最上面,就是应用层了,系统的一些应用和第三方开发的所有应用都是位于这个层次上,也许要纠结两者的差别,就是系统应用会用一些隐藏的类,而第三方的应用,总是基于SDK提供的东西来搞。
一般来说,Android开发,就是在SDK的基础上,吭哧吭哧用Java写应用。但自从有了NDK,一切有了写小变化。NDK的出现意味着,最上面应用层的内容,可以穿越Java部署的框架层,直接和底层暴露出来的,或者自行开发的C++库直接对话,当然在这些库中需要包含JNI的接口。
人说,这就不是Android也可以用C++开发应用么,但其实,这样的说法不够确切,纯C++应用,是无法被接受的。因为在Android中,大量的核心机制部署在框架层,它们都是用Java实现的,比如控件库,Activity的调度之类的。因此,没了界面,没了调度,还是只用C++做类库比较合适,否则一切都乱了套了。 »继续阅读
Tags:Android,移动 Posted in 技术
序
携来百侣曾游,忆往昔峥嵘岁月稠。 — 《沁园春·长沙》
对于Android,我也算是老人了,所谓,有文有真想。正由于这段玩票经历,使得我在毕业后,鬼使神差的成为移动平台的一名码工,再次有机会放肆的拥抱Android。
2010开年,手上突然有了一把闲散时间,有机会进一步总结和学习Android。于是想再一次为Android写一系列的东西,这些东西来自于一些开发经验,对源码的学习和对Android的浅薄认识,也算是鞭笞自己学习的一种手段。
其下所有内容,预计有十数篇,抑或更多。基本和技术相关,也许会配有一些其他相关比较闲淡的话题。可能会有一些具象实例,但更多的可能是自己的一些理解和认知。所有一切,源自于妄自挖掘,难免有疏漏或误解,观者淡定。
以此为序,有心者,望共勉。
Android简史
人生若只初识,何事秋风悲画扇。 — 《木兰辞》
要说当今移动平台的当红辣子鸡,Android说它是第二,也许没有别家敢认这个第一(好吧,iPhone,有意见就说…)。了解Android开发平台的过去和现状,除了往下看,另有便捷的方式就是在WikiPedia中键入Android,在这里,特此鸣谢GFW友情放生。
诞生
早在2005年7月,Google舞动着手中的美刀,收下了由Andy Rubin(传说中的Android之父…)等人创立的一家小公司,他们当时做的就是基于Linux内核的手机操作系统,也就是小时候的Android。经过Google多年打磨,Android在07年末,正二八经的粉墨登场开门接客。
自打一出生,Android便被钉板在富二代的角色上,不仅是因为老爹有钱的令人发指,也是因为其后有一帮金光闪耀的叔伯们保驾护航。这个叔伯群,便是响当当的开放手机联盟OHA(Open Handset Alliance)。这个联盟涵盖了中国移动、T-Mobile、Sprint这样的移动运营商,也包括HTC、Motolora、三星这些的手机制造商,同时还有以Google为代表的手机软件商,以Inter、Nvidia为标志的底层硬件厂商和Astonishing Tribe这样的商业运作公司(这公司是啥我也不晓得…)。作为后援团,他们理论上的任务,是各尽其长,全力捧红Android,实际上的任务是齐心协力,借Android东风赚一个盆钵满响。
当然,Android自所以被万众瞩目一炮走红,不仅仅是丫实在太有背景,同时,它也有这太多的新鲜的概念。Android是一个开源的平台(恩,真正的全面开源,是在发布后很久以后了…),它给那些捂着自家平台源码当宝的竞争对手们一记当头棒喝。Android自行研发了一套Java虚拟机,当时仅提供Java API的支持(NDK是更久以后的事情了…),号称为专为高端智能设计。Android开发环境支持所有主流操作系统平台,包括Windows,Linux,Mac,即便到今天,在手机开发中也是极其罕见的。Android的带头人Google,本身是做网络起家,Android内嵌大量Google网络应用,听上去就显得很酷。这所有的一切,共同造就了Android那鹤立鸡群,不染风尘的少侠形象。 »继续阅读
Tags:Android,移动 Posted in 技术