23
移动互联网开发笔记 vol 2 掌星 封面图片来源:Martin_Heigan ,CC授权

掌星 移动互联网开发笔记-Vol002

Embed Size (px)

Citation preview

Page 1: 掌星 移动互联网开发笔记-Vol002

移动互联网开发笔记 vol 2掌星

封面图片来源:Martin_Heigan ,CC授权

Page 2: 掌星 移动互联网开发笔记-Vol002

掌星 zhangxing.info

目录

- 征稿

- 在Android平台下定制系统的主屏幕

- IPhone开发内存管理

- Three20的使用

- iOS开发者计划申请流程攻略

- 雅虎画报IPad版本的开发经验介绍

- 刊首语

Page 3: 掌星 移动互联网开发笔记-Vol002

掌星 zhangxing.info

刊首语

终于到了第二期了,这次内容更加丰富,从一期的三篇笔记增长到六篇,而且还有来自淘宝口碑和中国雅虎的朋友的投稿哦

《掌星-移动互联网开发笔记》是致力于普及和推广移动互联网开发技术免费电子文档,虽然看起来目前还很简陋,但我们不断努力完善,和中国的无线互联网一同发展,希望大家多多支持。

Page 4: 掌星 移动互联网开发笔记-Vol002

掌星 zhangxing.info

征稿!!!

不管您是经验丰富的移动互联网开发人员,还是初涉移动互联网的菜鸟开发者,不管你是从事ipad, iphone,android, htm5开发,windows phone, webos, blackberryos, j2me 等平台开发,只要你觉得你自己的开发经验是对别人有帮助的,都可以投稿给《掌星》,我们的定位是技术笔记,不需要文章有华丽得辞藻或者多么高深的技术,只要是你在日常得项目中过的内容和技术即可。

投稿可以发邮件给 [email protected], 最好附赠您得联系方式,姓名和所在的公司,文章采用后我们会注明您的版权信息,并且有小礼物寄送哦。

Page 5: 掌星 移动互联网开发笔记-Vol002

掌星 zhangxing.info

在Android平台下定制系统的主屏幕作者:RainX (北京掌览天下信息科技有限公司)

概述:本文介绍如何在Android系统下,在不重新刷系统ROM的情况下,定制默认的主屏幕,使用这项技术,可以让你的应用代替系统默认的主屏幕,甚至屏蔽系统的主屏幕程序,把你的手机变成一个专有设备。

这个是我们之前的一个外包项目中用到的技术,之前的应用主要是利用手机的摄像头和网络,实现信息的采集功能。客户会将装有本应用的手机发放给客户的合作伙伴(比较多,大概有几百家),当然了,发放的目的当然是为了这个客户和合作伙伴和客户沟通使用的,所以所有的通信费用是这个客户方出的。但是客户有一个担心,由于手机不是专用设备,除了本应用之外,还有很多特有功能,很难避免具体的操作人员拿到手机之后,用它来打电话或者上网,这样客户就不得不承担多余的通信费用了,所以客户方的负责人提出了一个要求,让发放出去的手机在开机的时候就启动本应用,并且无法退出。

接到这个需求后,我们首先想到的是定制并重新刷系统的ROM ,将自己制作的应用声明为系统默认的Home Launcher, 不过考虑到不管从开发上,还是维护上这个方式的成本都有点过大了,所以就开始想如何能避开这个方式,单独从应用本身出发来实现这个功能。

首先,先解决第一个问题,如何在手机开机的时候默认启动这个应用,经过网络搜寻,这个并不难实现,大致的思路是,系统启动完成的时候,会发出一条广播,我们只需要用一个Receiver接收这条广播,并启动我们的应用即可。

首先是BroadcastReceiver的代码:(下页)

Page 6: 掌星 移动互联网开发笔记-Vol002

掌星 zhangxing.info

其中,RainXDemoActivity就是我们的应用程序的启动的Activity.

android.intent.action.BOOT_COMPLETED就是我们要捕获的广播,当然你的这个BroadcaseReceiver只接收这一条广播的话, if (intent.getAction().equals(ACTION)) 这条判断可以去掉。

有了代码还不够,我们还需要修改一下AndroidManifest文件,注册这个接收器,并且让我们的程序拥有对应的权限。我们需要在AndroidManifest.xml中加入

Page 7: 掌星 移动互联网开发笔记-Vol002

掌星 zhangxing.info

覆盖Activity类默认的onKeyDown实现,在里面,可以根据keyCode的值对指定的按键进行屏蔽,当keyCode的值是对应的按键的编码时,返回true就可以了,看上去是没什么问题了,运行一下才发现,奇怪,back按钮时屏蔽住了,但是对home按钮好像不起作用。google了一下才明白,对于Home这种硬按键,onKeyDown是无法完全的屏蔽的。

这样只能另想办法了,

在网站Google很一下,从锁屏软件那边得到了一些灵感,既然不能屏蔽Home键,那将点击Home键时的默认行为改为运行我们的程序就可以了,呵呵,于是,我们尝试了使用PackageManager 将程序注册为 android.intent.category.HOMEcategory的默认启动程序的方法实现。

代码如下

Page 8: 掌星 移动互联网开发笔记-Vol002

掌星 zhangxing.info

注意,要让上面的代码可以运行,我们同样需要在 AndroidManifest 文件中做一些调整,

在程序的启动Activity的intent-filter中,添加

然后,加入对应的permission.

如此,程序就作为系统的Home的默认Activity被启动了。

不过使用这个方式,需要注意下面几点:

1 pm.clearPackagePreferredActivities在部分机型或者部分发行版本下面不起作用,所以在第一次启动的时候或者点击Home按键的时候,可能需要手工的选择一下默认主屏幕。

2 new ComponentName ("com.android.launcher", "com.android.launcher.Launcher"); 这句是对应系统的默认Home Launcher 的packagename和启动应用对应的类,对于不同的机型,可能会有所不同,例如摩托罗拉的手机是:new ComponentName ("com.motorola.blur.home","com.motorola.blur.home.HomeActivity?");三星早期的手机new ComponentName ("com.sec.android.app.twlauncher","com.sec.android.app.twlauncher.Launcher");使用adw的手机new ComponentName ("org.adw.launcher", "org.adw.launcher.Launcher"); 或 new ComponentName("org.adw.launcher_donut", "org.adw.launcher_donut.Launcher");

为了支持多个机型,大家可以在程序里进行一个简单的判断,针对不同的机型做不同的处理。至此,客户的手机就转化为已我们的应用为唯一功能的专有设备了。

Page 9: 掌星 移动互联网开发笔记-Vol002

掌星 zhangxing.info

IPhone开发内存管理作者:侯波林 (北京掌览天下信息科技有限公司)

简介:

有用过iphone应用得人,肯定有经历过程序突然关闭得经历. 这不仅让使用者烦恼,更让开发者惭愧。为了不让我们得用户大喊 '吭爹呢这!',我们每一个开发者都必须对自己得应用负责. 我们知道,iphone OS对内存要求很严格,但凡有内存泄露,内存超额使用得应用都会被系统杀掉.为了不发生上面得尴尬场景,我们有必要了解一下iphone得内存管理机制.

基本概念:

iphone应用得开发语言是 Object-C, Object-C 采用得是基于引用计数得内存管理方式.即当一个对象得 引用计数不为0时,此对象不会被释放.只有当这个对象得引用计数为0时,才会被释放.

对象所有权:

所有权是iphone内存管理的核心思想,对象的所有者(不一定是创建者)负责对象使用完毕后的释放,一个对象可以拥有多个所有者. 拥有一个对象的所有权,可以有以下几种办法1 创建对象可以通过 alloc , new 以及 copy.

2 retain 一个对象. 伴随而来的是引用计数的规则问题 ,

1 当创建一个对象时,此对象的引用计数为 1 2 当 retain 此对象时, 对象的引用计数 +1 3 当 release 时, 此对象引用计数-1.

Page 10: 掌星 移动互联网开发笔记-Vol002

掌星 zhangxing.info

autorelease

1 在某些情况下,我们并不想取得对象的所有权,比如在某函数内返回一个创建的新对象,此时我们可借助自动释放池(NSAutoreleasePool),将所有权交给它。

2 快捷创建对象

3 抑或者,你不想时刻关注内存管理

IBOutlet和内存的那点事儿

在使用外部接口时,我们会使用如下方法声明属性:

需要注意到的是, 虽然在xib中的对象被创建时,引用计数为1,但随后他们会被自动释放, UIkit在重建对象间的结构时,会用到可用的setter(没有setter会自动retain),此时对象的引用计数依然是1,所有需要的dealloc中释放他们.

总之,我们要遵循的游戏规则是: 拥有一个对象所有权 -> 使用这个对象 ->放弃对象的所有权

Page 11: 掌星 移动互联网开发笔记-Vol002

容器的小秘密

NSArray: 当把一个对象添加到NSArray时,对象的引用计数会 +1,当把对象从 NSArray中remove时,对象的应用计数会减1.同样的规则也适用于 NSMutableArray当NSArray(或者类似的容器)被释放时,容器中所有的对象将被释放小结iphone开发内存管理的介绍就到这里了,理解了这些东西,再加上实践,相信你一定可以开发出越来越稳定可靠高效的应用了!

掌星 zhangxing.info

Page 12: 掌星 移动互联网开发笔记-Vol002

掌星 zhangxing.info

Three20的使用

作者:Gaosboy http://weibo.com/jiajungao (淘宝口碑)

前言

记:Three20(简称:TT)是Facebook维护的一个开源iPhone应用框架。框架封装了一系列视觉控件,网络组件,和工具方法。最近使用TT重构了一个app,这个app在1万行规模使用的是原生代码,架构非常简单。增长到2万行规模,这个原生的架构已经疲于应付迅速变化的业务需求,因此我们采用TT进行了重构。这里,简单介绍一下使用TT开发的app采用了怎样的架构,以及开发过程中的经验和教训。

app基于TTTableViewController的架构进行设计,主要分为三层:ViewControlelr,DataSource和Model。另外,平行于这三层设有Service和Util,封装一些通用逻辑和工具,例如:登陆,URLEncode等。最底层是Manager,封装网络控件,缓存控制等。除了这些还有独立封装的组件和对系统组件的扩展,如SegmentedControll,滚动图片等。这个架构不做赘述,说一说在这个架构下遇到的几个问题,以及解决方案。

TT对系统控件的封装无法满足个性化需求

TT对很多系统控件进行封装,拿之前提到过的TTTableViewController举例,所有的cell都被封装,对框架使用者透明,而TT封装的cell类型无法完全满足需求,我们往往需要格式更加丰富的cell样式。

在这种情况下,我们选择对TT方法进行重写。Objective-c提供指定类指定方法的重写,因此集中把需要个性定制的TT控件进行重写,完全不修改TT本身的代码。这样操作,既满足了需求,又使在日后对TT框架进行升级变的非常方便,几乎不需要考虑升级造成的不兼容。

Cell的默认操作过分单一

TT是使用Navigator和ULR的策略(欲了解该策略请参考TT官方网站 http://three20.info)来管理整个应用的ViewController的。在TableView中每一个cell带有URL,这个URL表明了点击cell后要跳转到的viewController,同时TT还认为如果一个cell没有URL那么他就是不可点击的,而往往存在这样的需求,cell可点击,但点击操作却不是跳转到某个ViewController。

Page 13: 掌星 移动互联网开发笔记-Vol002

针对这种情况,我们定义空URL,空URL不指向任意ViewController的类,而是指向nil。带有空URL的cell既可点击,又不会跳转到任意ViewController。

构造ViewController的URL不支持中文

之前说了,TT使用URL管理ViewController。有些ViewController的参数是中文,而且需要通过URL传递,而Navigator不支持汉字URL。

增加URLEncode方法,对每一个配置到URL中的参数编码,生成编码后的URL就可以正常使用。另外,TT会自动Decode的URL,无需开发者处理。

但TT的在URL策略中“/”无法使用,即使进行Encode之后,放入URL仍无法使用。这就需要开发者在构造URL过程中,检查每一个参数,确保不出现“/”。

稳定版TT(v1.0.5)不支持ios3.1及以下版

根据我们对客户端使用ios版本的统计,3.1及以下版的用户仍然占一定比例,还不能放弃支持。因此,考虑到支持3.1及以下版本的ios设备,需要使用v1.1 TT进行开发。开发过程中遇到的问题很多,以上是比较明显的几个,接下来聊一聊开发经验。

掌星 zhangxing.info

1、一个界面一个ViewController

在一个应用中,ViewController往往通过简单的配置就可以复用,可以控制多个界面,但我建议ViewController不复用。复用ViewController必然导致在类中出现用于区分不同界面的逻辑,如果界面上的逻辑稍有变动,这个被复用的Controller要跟着修改,随着发展,代码会越来越复杂,因此,保证一个界面一个ViewController。对于那些确实可以复用的逻辑,可以采用继承的方式。把可以的复用逻辑封装在一个类中,每一个直接控制界面的ViewController继承自这个父类,针对各自的个性逻辑重写相应的方法。

2、不过分使用URL

之前我们提到多次通过URL控制ViewController,Controller中的参数也可以通过URL传进去,但过度使用URL构造Controller可能会埋下隐患。URL不仅是初始化的时候使用,在运行过程中可能还需要使用这个URL在池中取出该对象。如果在URL中定义了多个参数,在获取对象的过程中,必须拿到这些参数值才能准确定位到相应对象,往往这些参数都不是全局的,所以这个过程就会非常麻烦。因此,在某些非终端的类中,尽量不使用URL构造对象,需要传递的参数使用ApplyQuery的方式,使用一个字典构造Query,使用URLAction构造对象。

3、封装两个网络控件,带缓存/不带缓存。

Page 14: 掌星 移动互联网开发笔记-Vol002

TT封装的网络控件叫TTURLRequest,在TTURLRequest中允许使用缓存,默认缓存1天。在应用中,有些请求要求实时性,不允许使用缓存,尤其是一些写操作的请求。应用本身也要对TTURLRequest进行一层封装,就是之前提到过的Manager,在NetworkManager中封装两个方法,使用缓存/不缓存。

4、使用延迟加载操作

所谓延迟操作,指的是在某个界面上加载某个组件的时候,如果直接调用addSubview方法可能会出现加载失败等诡异问题。是由于iPhone渲染一个界面需要时间,加载自己的组件需要在渲染界面之后,而调用viewLoad,甚至是viewDidLoad方法在TT框架下不能保证在渲染完成之后。因此在加载个人组件时,可能需要延迟加载,即,延迟0.3或0.5秒后再加载。TT框架本身也采用了许多延迟加载,使用[NSTimerscheduledTimerWithTimeInterval:(NSTimeInterval) invocation:<#(NSInvocation *)#> repeats:<#(BOOL)#>]方法。

以上介绍了8个经验和教训,希望能对大家在使用TT进行开发过程中提供一些帮助,少走弯路。

掌星 zhangxing.info

Page 15: 掌星 移动互联网开发笔记-Vol002

掌星 zhangxing.info

iOS开发者计划申请流程攻略作者:Chaoslawful (淘宝北京)

前言

要正式发布 iOS应用,App Store 上架步骤必不可少,而正式的 iOS应用发布、App Store 上架等动作,必须参与 iOS开发者计划才能做到。这里给大家介绍一下公司 iOS开发者计划申请的整个流程,并特别强调了需要注意的地方,以便让大家少走弯路。

准备工作

iOS开发者计划(iOS Developer Program,以下简称 iDP)有 3 种类型:

1. 校园计划(University Program) -免费。仅限高等教育机构申请,不可使用预发版本的 iOS(如 iOS 5b2),不可以专有设备列表(Ad Hoc)、App Store 或内部使用(In-house)形式发布应用,以此计划的证书签署的 iOS应用只能在参与计划的团队内部安装使用。

2. 标准计划(Standard Program) -年费 99 美元。可由任何个人或已注册公司或组织申请,除不能以内部使用形式发布应用外无其他限制。

3. 企业计划(Enterprise Program) -年费 299 美元。可由已注册公司或组织申请,主要用于发布内部使用的专有应用,除不能以 App Store 形式发布应用外无其他限制。

一般的个人开发者或公司只要申请参加标准计划即可。

需要提前准备的事项包括:

一台装有 Mac OS 10.6(Snow Leopard)以上版本的苹果电脑(iOS应用开发必须在 Mac OS 下进行)。以个人身份注册一个 Apple ID(以下简称 IDX)作为 iDP的申请者,申请成功后该 Apple ID 将被作为 iDP Team Agent 角色,拥有续费、应

用上架、修改团队成员等特权。

一张可进行美元支付的信用卡或其他银行卡(以下简称 CC),以便支付 iDP标准计划要求的每年 99 美元的费用,国内发行的 VISA 或MasterCard 双币信用卡均符合此要求。

Page 16: 掌星 移动互联网开发笔记-Vol002

公司申请时还需要额外准备:

1. 一个同 CC关联的 PayPal 账户(以下简称 PP),以便进行传真等费用的支付。2. 公司网站地址(以下简称 URL),一定得有,没有的话现赶一个出来吧……3. 公司英文名称(以下简称 LEN),发布在 App Store 上时会显示出来。国内注册的公司一般都没有正式英文名称,自行确定一个即可,

在 App Store 上先找找是不是已经有同名的公司,要避免重名!4. 公司注册地址的英文(以下简称 RADD),会用于确认公司真实性,一定要同公司营业执照上的注册地址一致!5. 公司注册地址的邮编(以下简称 PCODE),会用于确认公司真实性,一定要同公司营业执照上的注册地址一致!6. 公司 iOS开发事务联系人电话(以下简称 PHONE),申请时 Apple 会同联系人核实信息,一定要是有效的联系电话!7. 公司法人姓名、职位、联系电话、电子邮箱(以下简称 LINFO),法人姓名一定要同公司营业执照上的法人一致!8. 扫描的公司营业执照(以下简称 LIC),要盖上公司公章并在空白处写上后面获得的 Enrollment ID 及公司电话!,格式为:

Enrollment ID: xxxxxxxxxxCompany Phone Number: +86-区号-电话号码

9. 扫描的公司英文名称证明信(以下简称 PROV),要盖上公司公章!可参照下面的格式:

申请参加 iDP

iDP申请过程中需要填写的信息如无特别指明,一律要用英文或拼音!1. 访问 http://developer.apple.com,点击 iOS Dev Center 链接进入 iOS Dev Center 后点 Login 按钮,用 IDX的帐号密码登

录。2. 登录成功后,点击右侧栏中的 Join the iOS Developer Program。3. 默认的 iDP就是年费 99 美元的标准计划,直接点 Enroll Now 按钮确认,进入 iDP申请流程。4. 点击下方的 Continue 按钮进入第一步 Register as an Apple Developer,这里因为已经有了 IDX 账户,故可以选择 New

Apple Developer 一栏中的 I currently have an Apple ID I would like to use for my enrollment in an Apple Developer Program.

掌星 zhangxing.info

Page 17: 掌星 移动互联网开发笔记-Vol002

掌星 zhangxing.info

5. 随后需要选择参与计划的实体身份,如果是个人就点 Individual 按钮,如果是公司就点 Company 按钮。这里因为是公司申请,就点Company 了。

6. 现在会要求再次登录确认身份,继续用 IDX 的帐号密码登录后要求编辑公司信息,填好后点 Continue 按钮继续。各项信息填写方式如下:

• Legal Entity Name:填写之前准备好的 LEN名称• Legal Entity Type:选择公司类型,一般的商业公司都选 Company• Website:填写之前准备好的 URL 地址• Country:选择 China• Street Address:填写之前准备好的 RADD地址• City/Town:填写公司注册地城市拼音• State/Province:选择公司注册地所在省份• Postal Code:填写之前准备好的 PCODE邮编• Phone:填写之前准备好的 PHONE 号码,四个框分别是:国家号(中国是 86)、地区或城市区号(北京是 1)、电话号码、分机

号码(直拨无分机时留空即可)

7. 要求给出公司法人联系信息,分别按之前准备好的 LINFO 信息逐项填写,填好后点 Continue 按钮继续。8. 选择要参加的平台开发计划,选中 iOS Developer Program 即可,点击 Continue 继续。9. 最后审查一遍之前填写的所有信息,若有错误可逐次点击 Back 按钮回去修改,这是最后一次修改机会,请在确认无误后点 Continue

继续!10. 这时参与申请已经提交,会给出一个 Enrollment ID,该信息很重要,前面需要预先准备的资料很多都需要标注该信息,一定要记牢!

申请提交后 Apple 会进行初步审核,审核通过后会向 IDX 帐号注册的邮箱发送一封题为 Documentation Requested for Your Program Enrollment 的邮件,要求将企业法人营业执照和公司英文名称证明传真至给定的美国境内号码(这里假设是 +1(408)974-1053)。通常传真机收发国际传真价格都很昂贵,所幸有不少网站提供在线发送传真的服务,这里我们选用 http://faxzero.com,具体过程如下:

1 Sender Information 一栏中

Name:填写 IDX 帐号的注册人姓名的拼音Company:填写公司英文名称 LENFax #:可留空Email:填写 IDX 帐号注册邮箱

Page 18: 掌星 移动互联网开发笔记-Vol002

掌星 zhangxing.info

2. Receiver Information 一栏中

Name:填写 Apple Developer SupportCompany:填写 AppleFax #:填写之前邮件中要求的目的号码,这里填 1-408-974-1053,注意括号中的区号也要以横线连接!

3. 在传真文件中将 LIC和 PROV扫描件上传4. 选择 Send $1.99 Fax Now按钮发送传真。注意不要选 Send Free Fax Now,因为免费传真的调度优先级很低,可能十天半个月对方

都收不到!5. 点击按钮后会重定向到支付页,选择 PayPal 支付并使用 PP 账户付款6. 付款成功后稍等几分钟,IDX 注册邮箱中应该就能收到 faxzero发送成功的确认邮件。7. 传真成功后,向 [email protected]发送一封邮件以便提高 Apple 处理速度,附件中附上 LIC和 PROV扫描件,标题写

上 xxxx公司Apple开发者计划申请材料,正文参考以下格式:

上述资料传真成功后,等待约一周的时间(其间可能相关联系人可能会收到 Apple 客服的确认电话),若资料确认无误 Apple 就会给 IDX 注册邮箱发送一封题为 Apple Developer Program Enrollment Update 的邮件,点击其中的 Program License Agreement 链接确认同意 iDP的规定,然后就会提示支付年费,用之前准备的 CC卡支付即可。支付成功后等待一段时间,IDX 注册邮箱就能收到一封题为 Thank You for Joining an Apple Developer Program 的邮件,表示参与 iDP成功!

Page 19: 掌星 移动互联网开发笔记-Vol002

掌星 zhangxing.info

雅虎画报IPad版本的开发经验介绍作者:赵晓华 (中国雅虎)

一、前言

雅虎画报是将网站内容在IPad客户端展示的应用,以图片和少量文字为主,要求能支持离线浏览,支持横屏和坚屏。

二、数据格式

网站内容 xml数据库存储 sqlite图片存储到临时目录

三、程序结构

ClassGlobal 公共函数及常量Additions 对cocoa原有类的继承扩展Extensions 扩展类External 引用的外部类库

HttpClient 网络连接客户端JSON JSON相关操作类XML XML相关操作类Db 数据库相关操作类Image 图片处理相关操作OAUTH oauth认证类库FileManager 文件管理,临时文件处理相关类Debug 调试相关操作类UI 自定义和引用的一些ui样式类

Controller 控制层,负责程序间的调度Model 逻辑层,业务逻辑的相关代码View 视图层,自定义的UIView文件

Page 20: 掌星 移动互联网开发笔记-Vol002

四、开发中遇到的问题及处理方法

掌星 zhangxing.info

问题1:TableViewController在使用中,如果不断的上下滑动,内存的使用情况会不断增加

解决方法:

问题2:浏览过的图片不要重复下载,从本地缓存的文件中读取解决方法:

Page 21: 掌星 移动互联网开发笔记-Vol002

掌星 zhangxing.info

Page 22: 掌星 移动互联网开发笔记-Vol002

五、常用的开源类库

1. json json编码解码2. GTMBase64 base64编码解码3. TouchXML xml解析4. SFHFKeychainUtils安全保存用户密码到keychain中5. MBProgressHUD很棒的一个加载等待特效框架6. ASIHTTPRequest http等相关协议封装7. EGORefreshTableHeaderView下拉刷新代码8. AsyncImageView异步加载图片并缓存代码9. 类似setting的竖立也分栏程序

六、相关工具介绍

1.下载排名相关:appannie http://blog.blackwhale.at/2.用户行为分析: flurry http://www.flurry.com/3. majicrank-各国排名查询工具 (推荐) 4. AppViz-App销售统计软件 (推荐) 5. PodViz-用户评论等查看工具6.appfigures-报表统计分析工具 https://www.appfigures.com/

七、苹果开发相关的网址

http://www.cocoadev.com

http://www.cocoachina.com

掌星 zhangxing.info

Page 23: 掌星 移动互联网开发笔记-Vol002

http://zhangxing.info

专注移动互联网,我们和中国的移动互联网一同成长