Study on Android【一】–概述

This item was filled under [ study on android ]

from:http://www.cnblogs.com/duguguiyu/archive/2007/11/17/962325.html

 

如果你还不知道google的重磅炸弹Android(中文意思是机器人…感觉google取名字的天赋全部花在google这个词上了…)是什么,你可以看一下这里。如果你觉得挺没有意思,再看一下这里。如果还觉得不好玩,那下面的东西就不需要看了。。。

对我来说,Android还是很有吸引力的,不然一个MS技术的忠实走狗也不至于一下就投入java的怀抱。至于为什么?恩,等我有八卦精神的时候再使劲的侃。

在这里还是谈正事的要紧。这几天看了下Android SDK,编了几个练习,获得了一点点经验。简单的罗列一下,比较重要的内容都添上链接,也是方便我和所有需要的人查看。

 

按google的说法Android包括一个操作系统,一些中间件和核心应用程序。操作系统是基于Linux的,上面的东西用了些开源的、google也花了不少精力开发了其他一些东东。底层用的是C++,但所有供应用程序开发的API都是java的(伪托管操作系统?^_^)。具体内容可以看一下这里 。基本上不会与你闭着眼睛幻想的有太大区别。

Android的GUI框架,你可以从你本身的编程经验中看到很多的影子(对我而言主要是.net winform && asp.net,但感觉上很多理念与WPF类似,只是我对WPF只是走马观花的了解了一些*_*,谈不上有任何经验…)。

首先,在Android中,每一个需要显示并运行的程序都需要有一个Activity 类的派生类,从某个程度上来说它有点类似于Page的概念。每一个Activity从直观上来看就是一屏幕的内容,当你切换了屏幕,基本上就意味着你切换了一个Activity。Activity负责管理界面上的各个显示控件,最重要的,是它提供了基本的生命周期管理的函数,包括OnCreate, OnResume, OnFreeze, OnPause等等。从名字上,就可以大致看出这些函数所负责的内容,但你一定要明白他们具体分工的区别,具体情况查看一下这里 。但与Page不同的是,当一个Activity被切换出去的时候(你随时可能在你未完成所需事情的时候离开一个Activity,因为你用的是手机,你要随时准备接电话,准备迎接GF,准备与悄悄从后面摸过来的老板据理力争),你会希望回来还看到一样的内容。因此,你对Activity的生命管理尤其的重要(特别是当你了解了Android的进程管理的时候…),你可能需要在各个周期点上负责保管状态、恢复状态、传送数据等工作。

当你从一个界面切换到另一个界面的时候,就涉及到了Activity的切换。当你做这个工作的时候,你需要用到Intent,它包含切换所需的动作、(动作)分类、传送数据等信息。这个类的工作虽然简单,但内容丰富,建议仔细看看SDK,因为开发中你会反复与它打交道,而且可能你需要在两个Activity切换时做很多事情,比如传数据、做一些限定,都需要你对Intent比较熟悉。在配置文档中,你可以使用IntentFilter 对Intent进行过滤和匹配。在一个进程中,系统会维护一个Activity历史记录栈,以更好的维护Activity之间的交互。

在切换过程中(和其它一些场合),你需要传送数据。在Android中,你需要使用到一个Bundle 的类来传输。Bundle是其实一个key/value的map,不过它提供了很多API,用起来会比较方便。用这种统一格式来传输数据,在所需数据一定时会使判定比较简单,不需要太在乎是谁什么时候进行的传输。

每一个Activity还需要负责加载这个Activity所需要的显示的内容。显示的每一个部分称作一个view(你可以对应到control上),每一个都会处理键盘等交互事件、完成相应功能,并进行绘制。view的组织基本可以看成是一个复合模式,每一个view还会有相应的style,具体可以看这里。通过派生不同的view类,你可以定制你所需要的特定view(自定义控件…),它可以是简单的多view的特定布局组合,也可以是完成某种特殊功能。一般你会需要重载onDraw和onMeasure,具体可以看这里,规则还是有点小繁琐的。

但view的构造、layout的设定、样式的设定等等工作,通常不会使用显性的java代码进行编制,而是通过XML进行配置(WPF!!)。所有的资源也都是通过这种方式进行提供(查看这里)。而XML配置文件与代码的联系,是通过R类来进行的。R类是动态构造,它里面有一对的内嵌类,内嵌类里有一堆的静态int ID值。它是有系统自动根据配置文档的增删进行维护(in Eclipse…),完成从名字到ID的转换工作。而所有接受这种ID值的API,都会负责根据XML进行资源的配置。

Android的进程管理和资源管理都很有意思。通常,每一个应用程序(入口会是一个Activity的onCreate),都会占据一个进程。但这个进程是托管的!!你无法确定它何时会被回收,当系统进程空间紧张的时候,会依照优先级自动进行进程的回收(查看这里 )。由此可以看到,维护一个Activity的生命周期是多么的重要,因为它随时会被系统干掉*_*。同时,每一个应用程序的数据都是独享的。就是你存在数据库、文件的数据别的程序无法访问(其实根本是无法获知)。要在应用间共享数据,比较好的一个策略是把自己做成contentProvider,其他应用可以通过提交特定格式URL申请你的数据×—×(Why URL?…)。

除了Activity,还有就是server。顾名思义,这就是幕后英雄的角色。他们不在屏幕上占据任何位置,只是在后台默默工作。与他们交互的方法比较传统,主要是监听一些事件。当然很多时候这需要权限,因此你需要了解一些具体内容。

每一个应用都会有一个Manifest.xml,提供全局的配置。包括设置权限,设置各个Activity的属性等等。维护这个配置文件是一项基本任务(当你添加了新的Activity的时候),因为好像插件不会帮你完成这件比较琐碎的事情。

 

本来还看了其他更多的内容。写累了,不写了。其他等有了更多经验再慢慢写吧。如果想学个入门的话,还是建议好好看SDK。Doc基本上是把你看成一无所知(实际上,我就是这样*_*),而源码里也是包含海量的注释(只是时不时就有几个词打错…),连我如此弱的人都感觉看得不错,可想而知这SDK做的还是非常好的。。。

Bookmark and Share

Android大赛首轮获奖作品解析

This item was filled under [ GPhone使用 ]

from: http://www.cnblogs.com/duguguiyu/archive/2008/05/18/1201693.html

Android挑战赛第一轮前50的作品公布出来了,除了有4个暂时希望保密,其他46的介绍都已放出。虽然我大大的名落孙山之后,但不妨碍翻看这些作品,尝试思考一些手机应用的问题,尽情期盼下明天。这些作品,是由上百位领域专家,经过一套还算复杂的流程评 选出来的。我想,从中不仅仅可以看到Android的发展方向,也可以看到手机应用的一个发展趋势。如果你想在Android这块地盘上分一碗羹,或者, 期望在手机应用领域有所建树,也许,你应该去看看这些作品。于是,管中窥豹了一圈,准备扯一点,但我未做过正二八经的手机开发,对手机应用的见识十分浅 薄,期待讨论,严重的。

所谓手机

如果你还只是把手机看成打电话发短信的家伙,那么手机应用早不需要研究了。手机应用不但超越了打电话发短信如此本质的应用,并且已经翻过了拍照,听歌,玩单机游戏的境界,开始向各式各样的网络应用发展。这次获奖的作品中,基本所有的程序或多或少都和网络拉上了关系。。。
我觉得这个问题要从多方面看。首先是手机硬件和无线网络越来越强大,而这正好能和用户用来用强的信息处理需求相匹配。网络的使用能满足膨胀的信息需求,它像一个永不熄灭的活火山永远孜孜不倦的喷涌着各式各样的全新信息。网络也架设了一条更强大的人与人沟通的跨海大桥,传统的短信服务在其面前,只能算是一根过小溪的独木桥。。。
从另外一个角度看,网络的使用,也为更好的商业模式铺平了道路。虽然,与单机相比,手机上有稍微方便的付费方式(通过运营商…),但是,杯水车薪,解不了众人之渴。Google在web上做了一个活体的吸金机标本,移植过来,是自然而然的想法。。。

手机的优势
如果有一天,正如Google所期盼那样,手机真的可以随时在线了。下一个问题就应该是,手机的优势在哪?电脑与之相比,运算速度快,存储量大,网速快,屏幕大等等优势是显而易见的。但同显而易见的,是手机具有便携性(并开着机…),24小时随身相伴性及时性,等。在这次大赛中,优秀的获奖作品,很多,都充分的挖掘了这些优势。。。
当然,我们也不要忘了Android为手机带来的一些东西。随时在线的基础,一定的硬件门槛Google MapGoogle XMPP的引入,无疑都为很多很酷的应用提供了基础。。。

即时处理
如果有一天你在街上看到一个中意的商品,你会怎么办?如果你觉得价格偏高?如果你不确定内容是否喜欢?如果…?AndroidScan和goCart 这两个作品为你带来了新的模式。你通过相机拍下商品的条形码,软件会自动识别,并从网上为你找来商品详细的图文介绍,甚至还有一小段介绍视频、音频之类 的;同时,还能够为你提供此商品在其他地方的售价,配上Google Map,它甚至能够告诉你你附近哪家店卖的比这家便宜。。。
这样的快捷模式,放在家里的电脑不能给你,拍回家给LP参考的照片也不能给你,只有手机能够及时的处理这样的信息,为你提供全新的体验。这不是为谁做广 告,只是我觉得很cool,稍有点激动。用到这个特点的还有很多,比如Jigsaw可以快速的整理黑板上的数据(当然还是需要拍照片…)将它发给朋 友,PicSay可以让你拍下照片填上一两句话,立刻上传到网络上或者与朋友分享。这样的工作,你原来都需要回来家用电脑处理处理才能做到,通过随身携带 的手机,你可以把流程加速。。。
关于这点,我觉得还有很多可以挖掘的,比如对音频、视频的即时处理、更多更酷的图像处理等等,以此为入口,可以扩展成SNS,社会化网络,新搜索引擎之类的,这个方向之前没有很好的意识到,现在觉得,也许还真的大有可为。。。

让我知道你在哪里
Google Map + GPS + 随身携带的手机, 这意味着什么?有了GPS(或者其他能获得你具体位置的方式,作为手机的一个部件存在)和随身携带的特点就可以随时更新地理位置信息,有了Google Map(加上其他一些专业的网站,比如天气预报…)就可以了解这个位置所有可能需要了解的信息。在放出的46件作品中,有27件用到了Google Map。 想创意的时候我说,这是一个火热的方向,不要趟这堆浑水,但我没想到能热成这样,能有那么多应用被琢磨出来。比较直白的,当你来到一个陌生地方的时候,城 市导航、叫车服务、天气提醒、旅程的安排、美食计划等等,都有应用及时为您送上。这样的内容,可能是不认识的朋友,通过社会化了的网络为你打造。在此基础 上,有很多潜在的信息也被挖掘出来,比如有应用帮你计算出这个地域的安全信息,帮助你保护家人;当你家人所在的区域遇到紧急天气情况的时候,会及时通知 你;当你有朋友来到你这个地方的时候(或你前往某个城市想查看这里的朋友),你也会被通知到;当你所处的位置发生改变,你的手机配置也会发生变动,使你不 会遭遇领导讲话手机铃声响起的尴尬;还有真实信息的友人信息的交流和游戏;基于地理位置的定向的广告投放等等。。。
作品罗列的再多,也不会有更多的意思,如果再让我考虑做一个应用,这个方向我一定是优先考虑。我们通常在电脑上用Google Map的时候,位置信息都是我们自己干巴巴的输入的,只有在手机上,这一维信息才真正的动了起来,不再需要手动的输入,使用越简单的应用肯定会越受欢迎 的。。。

沟通和协同
我很坚定的相信,迟早有一天我们会忘记短信。IM进驻手机占山为王是迟早的事情。短信的应用都是基于服务站的尽力转发模式,而基于互联网的,不但有更大的 带宽,更自然的接入方式,还可以进行更好的协同。因此,我们看到一些比较有特点的IM软件,比如基于手绘图片的聊天(IMEasy,这可能是唯一一个中国 人的获奖作品…),基于多媒体的聊天,都成为获奖者。Google XMPP的提供,其实就是为了做这件事情的。而基于协同的绘图,日志安排等软件也相继出现。手机,在这里,是纯粹作为类似于电脑这样的信息处理节点的一个 便携延伸。。。
所以,电脑有一个,你也可以类似在手机上来一个,只要是可以消遣时间或需要及时处理的,我觉得都可以有一席之地。。。

从手机的特点出发,我觉得,上面三点可以涵盖大部分的作品的特点。当然还有一部分作品,比如虚拟磁盘,基于生物信息的认证,单机概念的游戏等等,这是把手机作为一个单一机器来做的,肯定必须,但姑且不提。。。

聚合、SNS、社会化
在我的概念里这都是web2.0的理念,将不同人创造的消息统一的推到你的面前。在我看来,搜索、聚合、社会化都一样,只不过搜索是把不规矩的信息收集起 来放在你面前,聚合是把规矩的信息推到你的面前,而社会化,是通过组织好的路径,把消息放到你的面前。我一直把SNS之类的社会化东西分成两类,一类是将 物理世界的人际关系映射到网络中来;另一类是根据人的兴趣建立一个全新的虚拟关系。我有两个离不开的SNS网站,一个是校内,一个是豆瓣。

在校内,认识的 人都是我现实的朋友,或基于这些朋友扩展而来的朋友,我关注他们的生活,一切开心与不开心,如果是陌生人,我通常不会有很浓厚的兴趣;在豆瓣,大部分人在 生活中我都不认识,之所以成为好友,可能是因为一本书、一部电影、一张CD。在我看来,前者一定要做到庞大的,包含进所有朋友,我只希望用一个,使得一次 更新所有人都能够看到;而后者需要做到专业和专注,不同的兴趣在不同的网站分享(当然,网站不乐意了,他们希望他们什么都有,什么都有什么都好当然是最 好,这相当于合二为一,怕只怕,什么都有什么都不精…)。。。
在获奖的作品中,可以看到有很多希望通过某种兴趣来搭建的网络,比如通过共同喜好的菜,共同喜好的一段音乐,共同喜欢的一段旅途。不过,这个不是我想强调的重点。我想说,及时的位置信息更新,会像一根巨大的搅棒一样,加速虚拟与现实的人际关系的交融,也许你们身处异地,互未谋面,因为某个兴趣相识,但某天你突然发现他来到你家门口的球场来看球了,很快认识成了真实的朋友。及时性,是这个搅棒力量的保障,手机,就会是这个搅棒的载体。当然,目前还是我YY的成果,没有任何理论支持。。。

差异
一路看下这Top50的作品。我会觉得有些想法匪夷所思,究其原因,有些可能是因为我个人的状况,更多的应该是因为中国与外国的经济、文化、信息化的差异所致。。。
在作品中,有好几个是关于汽车的管理,共同驾驶人的寻找之类,可能是因为我一个穷学生,我无法想象到这样的应用,但我更相信,这是由于中国普遍经济能力较 低,没有这类的需求;而有好几个作品是为了降低尾气而做的,环境,在中国还是一个很不受重视的方面;社会化,在这些应用中几乎是无处不在,我觉得这很重 要,但没想到如此频繁,我一直很歪曲的觉得,这是老外的倾诉欲望太强所致。。。
总之,我觉得这Top50,要摆到中国来评,肯定会大大的不一样。而我们应该清醒的区分这种差异产生的原因,如果是因为信息化程度不同所致的,我觉得就应该及时跟上,走在前面;而如果是由于文化差异所致,就不要依葫芦画瓢,落一个东施效颦。。。

未来的路
以下内容,纯属自言自语:我的Chamberlain(简单的,可以看成一个手机搜索…)最后的参赛平均分是B(每25%是一个档,B相当于前25% 至50%),除了在Effective use里面拿了个A,在Polish,Indispensability和Originality中都是B。我想我搞错了主次关系,原来我觉得网络只是手 机信息的一个载体,搭建好平台比想好应用更重要,现在我觉得,单机的检索应该作为网络的辅助而存在,有效的应用比平台更为重要。因为网络不但可以带来更丰富的信息源,还可以带来有效的商业模式,而只有最好的应用作标签,所谓的平台才可能推广成规范。。。

Bookmark and Share

G1技巧50篇合集(一)

This item was filled under [ GPhone使用 ]

 使用T-Mobile G1手机的用户一定会发现Android系统中有很多实用的技巧,本周末Android123整理出G1技巧50篇可以值得HTC Dream用户参考和学习。转载请保留来自www.android123.com

  1.自定义Home屏幕

  你可以将任何图标长按拖动到桌面上,也可以长按图标拖动到Home屏下部的菜单区域直到变成删除标识就可以清理桌面。

  2. 快速E-mail设置

  你可以设置大多数的POP3或IMAP邮件帐户,在E-Mail客户端中按下Menu键-找到Accounts,直接输入电子邮箱的地址和密码即可。

  3. 邮件默认设置

  G1使用了优化过的GMail程序作为帐户在首次激活Android手机时,如果你使用其他帐户,记住单击Send email from this account当你设置其他的邮箱时。

  4. 检查新邮件
你可以设置每5分钟自定检查新邮件,在Email程序中,按下Menu键,在帐户Account设置中修改邮件检查频率。.

5. 检查你的SD卡容量
  如果需要知道你的SD卡还有多少空间,在桌面上按下Menu键,选择Settings,滚动列表到SD card & phone storage即可看到.

6. 节省空间

  随着Android Market软件的增多G1内部的可用存储会变得越来越紧张,G1内部的空间在74MB左右,如果不需要一些程序可以考虑删除了,参考如何删除已安装的Android软件 介绍的方法。

7. 节省电量

  像大多数智能手机一样,G1的电池问题显得比较突出,如果你完成操作应该按下结束通话(红键)关闭屏幕.

8. 节电技巧2
降低屏幕亮度,在Settings中进入Sound & display滚动到Brightness调节适合你的亮度,同时设置屏幕超时自动关闭背光的时间到15秒最小值.

9. 省电技巧3
平时不需要时应该关闭WiFi、GPS和蓝牙,如果你不使用3G网络应该在Settings-Wireless controls的Mobile networks中勾选Use only 2G networks’ 这项以最大限度节省电量.

10. 节点终极方法

 平时可以关闭来电和短信的震动提醒. 

11. 提示屏幕

  将你的手指按住屏幕顶端拉下可以看到各种提示比如新Email、未接来电、下载完成等其他提示.在开发中对应NotificationManager类

12. 街景地图

  Google Maps现在包含了360度的街景显示效果,在Maps程序中按下Menu键,选择Map Mode中的Street View即可,当然部分国家目前还不支持街景模式显示,比如中国。

13. Street View问题
 为什么目前Street Views在英国和法国不支持,然而西班牙、意大利、比利时、美国和日本都支持,这主要取决于Google街景拍照车的速度和当地的法律等综合问题。

14. 屏幕错误
  G1使用的电容式触摸屏优势相对的按压可能出现操作错位等问题,不过和Windows Mobile手机中的电阻式LCD相比更适合大面积触摸操作,在成本上也高出了不少,一般不需要校对屏幕。.

15. 安全
  防止陌生人使用或保证隐私机密文件的安全可以设置手势解锁功能,在Settings的Security & location设置unlock pattern这时你滑出自己个人的解锁图案即可保证安全,同时你不一定需要把九个点都连上在网格中。

16. 播放视频

  G1目前没有自带播放器,可以在Market上下载aPlayer进行视频播放,目前Android支持MPEG4和3GPP文件格式,当然可以使用PC平台上的Android视频转换王处理播放。

17. 切换网络
就像iPhone一样,G1在购买时一般签订有至少18月合约,当然你可以购买unlocked code解锁码来解决SIM卡的锁定。一般解锁码售价在250元人民币左右。

18. 升级的扩展卡
  购买G1时附送了一张高速的microSD卡由Sandisk制造但容量仅仅为1GB,你可以购买8GB的microSD卡售价在130元人民币或16GB的SDHC卡售价在300元左右。

19. 快速搜索

  Google提供了搜索栏,可以直接添加Widget使用谷歌的搜索,同时还有Voice Search程序可以直击使用语音搜索功能。

20. 快捷键启动程序

  你可以通过快捷键启动程序,当然这仅仅适用于G1这样包含QWERTY键盘的Android手机,按下Menu键,在Settings中找到Applications进入Quick launch即可设置。.

 有关G1技巧50篇的21-30篇可以帮助你解决Android Market中存在的一些问题,以及htc dream通过usb数据线连接pc需要注意的。

 21. USB安全

 默认情况下Androi并不支持USB和PC连接,你必须设置做以下设置,在桌面上按下Menu键,进入Settings-Application-Develeopment后开启USB debugging这项功能才可以,同时需要安装Android驱动,可以查看Android驱动 下载解决。

22. 安装非Market上的软件

为了安全起见,默认情况下G1不能安装从网站上下载的APK文件或使用APK安装器解决,可以通过按下Menu键,选择Settings-Application-Unknown sources勾选这项,点许可协议即可。

23. 任务切换

 如果你在浏览网页时需要打开一些其他程序,可以通过长按Home键来实现任务切换,当然短按后直接会跳到桌面上,需要注意的是系统默认只显示最近6个任务。

24. 开启 Wi-Fi

 在Settings-Wireless controls-Wi-Fi settings中可以搜索到当前的WiFi HotSpot,附件没有WLAN AP的可以使用更快的方式浏览网络,Android支持IEEE 802.11g,最大支持54Mbps的传输,当然更方面的是可以在Market上下载aSettings进行设置。

25.快速静音模式

 除了一直持续的按音量降低键外,长按结束通话键可以直接选择菜单中的Silent Mode即可快速进入静音模式。 

26. 联系人收藏

Android的Contacts联系人程序支持收藏经常联系人作为一组,只需要在联系人详细信息对话框中勾选“星”型图标即可.

27. 转发短信或彩信

在Messaging程序中长按信息列表中的某项,直到弹出菜单,选择Forward即可实现转发操作。

28.自动对焦

  G1的320万像素摄像头支持自动对焦功能,可以半按快门键的同时HTC Dream的拍照硬件会自动调整焦距,这时可能会听到电机的声音这是正常的。只有对焦成功才能拍出来的更清晰尤其是微距情况下。

29. 获取当前方位
  G1包含了指南针功能,依次进入Maps程序,按下Menu键选择Map mode-Street view然后再次按下Menu键,选择Compass即可知道你当前的方位了。

30.了解手机串号

  在拨号界面上按下*#06#会显示G1的IMEI串号,同时在About Phone中也可以找到这个手机身份定义值。

本周我们主要整理下Android手机 G1的31-40的使用技巧。帮助HTC Dream用户了解有关快捷键,Android系统中如何使用复制、粘贴这样的功能。

31.浏览器快捷键

  使用T-Mobile G1网友可以使用QWERTY键盘通过快捷键来实现操作,使用Menu+J键盘后退、Menu+K前进,Menu+空格键可以转到主页,而Menu+H键可以查看浏览历史记录。

32.文本复制和粘贴

  其实本身G1是支持复制和粘贴的,和Windows相比,仅仅是Ctrl键被换成了Menu键,比如剪切为Menu+ x,而复制为 Menu + c ,最后的粘贴变为了Menu + v ,整个操作还是十分方便的,还有Android系统在一些地方长按会弹出快捷菜单,一般都包含了复制和粘贴的功能。

33. 收发彩信

  由于彩信收发,G1并没有提供CMCC的APN MMS GPRS接入点,T-Mobile的APN并不适合中国大陆,但Android系统本身是支持的,我们可以设置一个MMS的APN,设置好移动梦网的代理就可以接收了,不过还是不推荐使用,详细方法可以查看Android论坛的内容解决。

34. 恢复出厂设置

  如果系统产生了换乱,或需要快速删除手机中的联系人、已经安装的所有软件可以通过恢复出厂设置来解决,该过程是不需要重新网络解锁的,但需要使用Gmail帐户连接Google服务器来激活Android操作系统,这里需要用到3G或GPRS连接进行数据传输,整个过程需要CMNET的流量,但部分用户会发现恢复后无法进入系统,这个问题主要是固件bug自身的原因,如果遇到这种问题,可以刷回Google官方的原版固件即可,2009年4月底到5月T-Mobile会推送包含cupcake更新新版android固件,解决中文输入、中文界面等问题。

35. 多页面流量

  如果你当前打开了很多个网页可以通过按下Menu键,选择Windows来切换选择,Android默认情况下最大打开的网页数量在10~12左右,一般没有特别需要不建议打开太多网页,以防止减少运行内存的消耗而影响整个系统的速度。

36. G1可以刷OMS吗?

  G1在硬件方面运行OMS是没有问题的,目前多普达Magic已经有运行版本出现,但部分功能会不支持的,比如手机电视中CMMB选项,G1没有这个硬件无法使用。但OMS包含了很多中国移动定制程序,没有特别需要还是建议使用Android操作系统比较好

37. G1使用什么无线路由器好

  这里如果在国内,使用TP-LINK W340R比较好,在兼容性方面普联的WiFi路由包含了4个以太网接口可以连接4个有线设备,支持54Mbps的IEEE 802.11b/g协议,支持MAC防火墙、WEP加密增强等等,提供了7种播放方式可以解决大陆地区的所有中国电信、联通(网通)的ADSL验证问题。售价在155元人民币。

38. 一般HTC Dream的待机多长

  通常情况下关闭蓝牙、GPS、不用WiFi每天通话15分钟,收发短信3条,大约可以使用3天,而在信号不稳定,经常播放音乐、上网仅仅只能使用1天,通常情况下使用MiniUSB接口也可以充电,但可能会对ExtUSB接口外形有影响。

Bookmark and Share

Tutorial: Notepad Exercise 1

This item was filled under [ 一步一步学习 ]

 

In this exercise, you will construct a simple notes list that lets the user add new notes but not edit them. The exercise demonstrates:

  • The basics of ListActivities and creating and handling menu options.
  • How to use a SQLite database to store the notes.
  • How to bind data from a database cursor into a ListView using a SimpleCursorAdapter.
  • The basics of screen layouts, including how to lay out a list view, how you can add items to the activity menu, and how the activity handles those menu selections.
通过这个练习,你将会构造一个简单的只能让用户写东西,但不能编辑的记事本。
这个练习演示了:
  • ListActivities 基础和创建处理菜单项
  • 使用SQLite保存数据
  • 使用一个简单的指针适配器把数据从一个数据库指针转换成一个列表
  • 屏幕排版的基本原理,包括排版一个列表数据,如何添加一个条目到activity(指当前活动的窗口啦)的菜单里,和activity如何控制那些菜单选项的

下面的懒得翻译了,自己慢慢看。。。。

md。。还是翻译下。。。认真做一遍。。。

Step 1

Open up the Notepadv1 project in Eclipse.

Notepadv1 is a project that is provided as a starting point. It takes care of some of the boilerplate work that you have already seen if you followed the Hello Android tutorial.

  1. Start a new Android Project by clicking File > New > Android Project.
  2. In the New Android Project dialog, select Create project from existing source.
  3. Click Browse and navigate to where you copied the NotepadCodeLab (downloaded during setup). Select Notepadv1 and click Choose.
  4. You should see Notepadv1 in the Project name and also see the Location filled in with the path you selected.
  5. Click Finish. The Notepadv1 project should open and be visible in your Eclipse package explorer.

If you see an error about AndroidManifest.xml, or some problems related to an Android zip file, right click on the project and select Android Tools > Fix Project Properties. (The project is looking in the wrong location for the library file, this will fix it for you.)

Step 1

在eclipse里打开 Notepadv1项目

Notepadv1是一个起点,如果你已经看过Hello Android教程,那你应该知道他处理了类似吃饭前洗碗的事情(做准备工作啦)。

  1. 通过点击 File > New > Android Project.开始一个新的android项目
  2. 选择 Create project from existing source.
  3. 点击Browse ,然后导航到你放着NotepadCodeLab ( setup阶段下载的文件)的地方. 选择 Notepadv1 .
  4. 你将看到Project name是 Notepadv1,然后看到Location字段填这你选择的路径(废话)
  5. 点击 Finish.  Notepadv1 将被打开并在你的eclipse包管理器里可见。

If you see an error about AndroidManifest.xml, or some problems related to an Android zip file, right click on the project and select Android Tools > Fix Project Properties. (The project is looking in the wrong location for the library file, this will fix it for you.)(这段说如果有错误该怎么办啦,貌似他提供的方法没用,我的错误是重复定义了R类,直接把其中一个文件删掉就可以了)

Step 2

Take a look at the NotesDbAdapter class — this class is provided to encapsulate data access to a SQLite database that will hold our notes data and allow us to update it.

At the top of the class are some constant definitions that will be used in the application to look up data from the proper field names in the database. There is also a database creation string defined, which is used to create a new database schema if one doesn’t exist already.

Our database will have the name data, and have a single table called notes, which in turn has three fields: _id,title and body. The _id is named with an underscore convention used in a number of places inside the Android SDK and helps keep a track of state. The _id usually has to be specified when querying or updating the database (in the column projections and so on). The other two fields are simple text fields that will store data.

The constructor for NotesDbAdapter takes a Context, which allows it to communicate with aspects of the Android operating system. This is quite common for classes that need to touch the Android system in some way. The Activity class implements the Context class, so usually you will just pass this from your Activity, when needing a Context.

The open() method calls up an instance of DatabaseHelper, which is our local implementation of the SQLiteOpenHelper class. It calls getWritableDatabase(), which handles creating/opening a database for us.

close() just closes the database, releasing resources related to the connection.

createNote() takes strings for the title and body of a new note, then creates that note in the database. Assuming the new note is created successfully, the method also returns the row _id value for the newly created note.

deleteNote() takes a rowId for a particular note, and deletes that note from the database.

fetchAllNotes() issues a query to return a Cursor over all notes in the database. The query() call is worth examination and understanding. The first field is the name of the database table to query (in this case DATABASE_TABLE is “notes”). The next is the list of columns we want returned, in this case we want the _id,title and body columns so these are specified in the String array. The remaining fields are, in order: selectionselectionArgsgroupByhaving and orderBy. Having these all null means we want all data, need no grouping, and will take the default order. See SQLiteDatabase for more details.

Note: A Cursor is returned rather than a collection of rows. This allows Android to use resources efficiently — instead of putting lots of data straight into memory the cursor will retrieve and release data as it is needed, which is much more efficient for tables with lots of rows.

fetchNote() is similar to fetchAllNotes() but just gets one note with the rowId we specify. It uses a slightly different version of the SQLiteDatabase query()method. The first parameter (set true) indicates that we are interested in one distinct result. The selection parameter (the fourth parameter) has been specified to search only for the row “where _id =” the rowId we passed in. So we are returned a Cursor on the one row.

And finally, updateNote() takes a rowIdtitle and body, and uses a ContentValues instance to update the note of the given rowId.

 

Step 2

我们研究下 NotesDbAdapter 类—这个类提供了一个对保存着我们的记事本数据的SQLite数据库访问的封装,并提供给我们更新数据的接口。

在类的最开头是一些我们在应用程序里用到的常量定义,这些是用来从数据库里查找数据的属性定义(其实就是数据库字段啦). 同时还要一个数据库创建字符串定义,如果数据库还不存在的话,就会用来创建咯(废话).

我们的数据库名是 data, 然后只有一个表叫 notes, 这个表有3个字段: _id,title and body. _id是一个有下滑线(其实是在AndroidSDK里使用了很多次的习惯啦,就是你也可以不用下划线,不过还是用比较好,这样比较统一)的用来帮忙跟踪数据的(其实就是针对每条数据,有个唯一的标记啦)。 当查询或更新数据库时通常会用到,另外2个字段用来保存数据的文本字段.

NotesDbAdapter构造器有一个上下文参数,这样使得他可以跟Android操作系统的某些相关方面联系到一起. 通过某种方法与Android操作系统取得联系在类里很常见. Activity 类实现了Context 类,所以你在你的Activity里需要上下文时,你只要调用this就行了(其实这段就是说某个类如何跟操作系统级别数据进行通信啦,就是通过context参数,因为Activity类是context类的实现,所以在activity类里调用this指针就ok了)

 open()方法为我们创建并打开一个数据库,他首先调用了DatabaseHelper的一个实例,DatabaseHelper是SQLiteOpenHelper类在我们本地的一个实现。 然后调用了 getWritableDatabase()。

close() 方法关闭数据库,释放跟这个数据库连接有关的资源。

createNote()方法 需要输入新记录的title和body的字符串这2个参数,然后在数据库里创建该记录。并且臆断这个新记录创建成功,这个方法返回新建记录的rowId,不成功返回-1。

deleteNote()方法 输入指定记录的rowId然后删除该记录。

fetchAllNotes()发出一个返回数据库里所有数据的指针的数据库查询语句。query()方法很有必要好好解释理解下。第一个字段是要查询的数据库表名(在这个例子里DATABASE_TABLE是"notes").下一个参数是我们想要的字段列表,在这个例子里我们需要the _id,title 和body 列,所以我们在string数组里指定了。剩下的参数依次是: selectionselectionArgsgroupByhaving and orderBy. 使得这些都是null意思是,我们需要所有的数据,不要分组,使用默认顺序。查阅 SQLiteDatabase 获得更详细的信息。

注意:返回一个指针比返回一个数据集好。这样使得Android能更有效的使用资源–不是直接扔一大堆数据到内存里而是在必要的时候获取和释放,当数据库表有很多数据时,这样做效率相对高很多。

fetchNote()方法类似 fetchAllNotes()方法,但是只获取一条我们输入的rowId对应的记录.他使用一个稍微有点不同的版本(指输入不同参数)的SQLiteDatabase query()方法。第一关参数(设置成true的)是指我们只要一个完全不重复的结果.selection 参数(第4个参数)被指定说只搜索”where _id =” 我们传入的 rowId 的行. 所以我们返回一个只有一行的指针。

最后,updateNote() 方法输入 rowIdtitle and body参数,然后使用一个ContentValues 实例来更新与我们指定的rowId对应的记录。

 

Step 3

Open the notepad_list.xml file in res/layout and take a look at it. (You may have to hit the xml tab, at the bottom, in order to view the XML markup.)

This is a mostly-empty layout definition file. Here are some things you should know about a layout file:

  • All Android layout files must start with the XML header line: <?xml version="1.0" encoding="utf-8"?>.
  • The next definition will often (but not always) be a layout definition of some kind, in this case a LinearLayout.
  • The XML namespace of Android should always be defined in the top level component or layout in the XML so that android: tags can be used through the rest of the file:xmlns:android="http://schemas.android.com/apk/res/android"

Step 3

打开在res/layout里的 notepad_list.xml 文件研究下他(你需要点击底部的xml标签才能查看xml的代码)。

这是一个几乎是空的布局定义文件。这里有些你需要知道关于布局文件的概念:

  • 所有的Android布局文件必须以 <?xml version="1.0" encoding="utf-8"?>开始。
  • 下一行一般是(但不一定啦,可能是别的)某种布局定义,在这里是一个 LinearLayout.
  • 这个android的xml命名空间必须在最上层组件或布局里定义,这样android:tags才能在文件接下来的部分使用:xmlns:android="http://schemas.android.com/apk/res/android"

Step 4

We need to create the layout to hold our list. Add code inside of the LinearLayout element so the whole file looks like this:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

  <ListView android:id="@android:id/list"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
  <TextView android:id="@android:id/empty"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/no_notes"/>

</LinearLayout>
  • The @ symbol in the id strings of the ListView and TextView tags means that the XML parser should parse and expand the rest of the id string and use an ID resource.
  • The ListView and TextView can be thought as two alternative views, only one of which will be displayed at once. ListView will be used when there are notes to be shown, while the TextView (which has a default value of “No Notes Yet!” defined as a string resource in res/values/strings.xml) will be displayed if there aren’t any notes to display.
  • The list and empty IDs are provided for us by the Android platform, so, we must prefix the id with android: (e.g., @android:id/list).
  • The View with the empty id is used automatically when the ListAdapter has no data for the ListView. The ListAdapter knows to look for this name by default. Alternatively, you could change the default empty view by using setEmptyView(View) on the ListView.More broadly, the android.R class is a set of predefined resources provided for you by the platform, while your project’s R class is the set of resources your project has defined. Resources found in the android.R resource class can be used in the XML files by using the android: name space prefix (as we see here).

Step 4

我们需要创建一个布局来放我们的列表。添加代码到 LinearLayout元素里,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

  <ListView android:id="@android:id/list"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
  <TextView android:id="@android:id/empty"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/no_notes"/>

</LinearLayout>
  •  在 ListView 和TextView标签里的id字符串的@ 符号意思是XML解析器可以解释和扩展接下来的id字符串并当做ID资源来使用。
  •  ListView 和TextView可以被认为是2个可选的视图,每次只有一个可以被现实。当记录被显示的时候使用ListView, 如果没有记录来显示的时候,textView将会被显示(在 res/values/strings.xml里定义了字符串资源 “No Notes Yet!” ) 
  • 这个列表和空的IDs是由android平台提供给我们的,所以,我们必须给id加上android:前缀(比如,@android:id/list).
  • 当list适配器没有数据给listview时,这个空的id视图会被自动使用。list适配器知道查找默认的名字。你也使用 setEmptyView(View) 可以改变默认的空视图.另外,当你的项目的R类已经定义时,android.R类是平台预先定义好给你用的资源(??不知道啥意思).在android.R资源类里找到的资源可以在xml文件里通过android:name 前缀使用。

Step 5

To make the list of notes in the ListView, we also need to define a View for each row:

  1. Create a new file under res/layout called notes_row.xml.
  2. Add the following contents (note: again the XML header is used, and the first node defines the Android XML namespace)
    <?xml version="1.0" encoding="utf-8"?>
    <TextView android:id="@+id/text1"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    This is the View that will be used for each notes title row — it has only one text field in it.

    In this case we create a new id called text1. The + after the @ in the id string indicates that the id should be automatically created as a resource if it does not already exist, so we are defining text1 on the fly and then using it.

  3. Save the file.

Open the R.java class in the project and look at it, you should see new definitions for notes_row and text1 (our new definitions) meaning we can now gain access to these from the our code.

 

Step 5

为了在listview里创建记录列表,我们需要为每一行定义一个视图:

  1. 在res/layout目录下创建一个文件notes_row.xml.
  2. 添加以下内容 (注意: 这个xml头部再次被使用,第一个节点定义了android xml命名空间)
    <?xml version="1.0" encoding="utf-8"?>
    <TextView android:id="@+id/text1"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    这是每个记录标题行的视图,他只有一个字段。

    在这里我们创建了一个新的id叫text1. id字符串里那个在@后面的加号表示这个id如果不存在可以被自动创建为一个资源所以我们很匆忙的创建并使用了他

  3. 保存文件

打开项目里的R.java类研究下他,你将会看到notes_row 和 text1的新定义,同时我们可以在我们的代码里有了访问的权限。

 

Step 6

Next, open the Notepadv1 class in the source. In the following steps, we are going to alter this class to become a list adapter and display our notes, and also allow us to add new notes.

Notepadv1 will inherit from a subclass of Activity called a ListActivity, which has extra functionality to accommodate the kinds of things you might want to do with a list, for example: displaying an arbitrary number of list items in rows on the screen, moving through the list items, and allowing them to be selected.

Take a look through the existing code in Notepadv1 class. There is a currently an unused private field called mNoteNumber that we will use to create numbered note titles.

There are also three override methods defined: onCreateonCreateOptionsMenu and onOptionsItemSelected; we need to fill these out:

  • onCreate() is called when the activity is started — it is a little like the “main” method for an Activity. We use this to set up resources and state for the activity when it is running.
  • onCreateOptionsMenu() is used to populate the menu for the Activity. This is shown when the user hits the menu button, and has a list of options they can select (like “Create Note”).
  • onOptionsItemSelected() is the other half of the menu equation, it is used to handle events generated from the menu (e.g., when the user selects the “Create Note” item).

Step 6

下一步,打开源代码里的Notepadv1类. 在接下来的步骤里,我们将要改变这个类,让他变成一个使我们可以添加、显示我们的记录的list适配器

Notepadv1将会继承 Activity的一个子类 ListActivity,他包含关于处理list的额外的功能,比如:在屏幕上显示任意数量的list条目,移动条目,并使条目可选中。

查看下已经在Notepadv1类里的代码.有一个现在还没使用的私有字段mNoteNumber,我们会用它来创建数字化的记录标题。

也有3个覆盖的方法: onCreateonCreateOptionsMenu 和onOptionsItemSelected; 我们研究下他们:

  • onCreate() 方法在一个activity开始时被调用—有点像一个activity的 “main”方法 .在一个activity运行时,我们用这个来设置 他的资源和状态。
  • onCreateOptionsMenu()方法用来为activity创建弹出式菜单,当用户点击菜单按钮时,他会显示一个选项列表(比如“创建记录”).
  • onOptionsItemSelected()方法是另一个菜单反应,他用来处理菜单产生的事件(比如,当用户选择“创建记录”时)。

Step 7

Change the inheritance of Notepadv1 from Activity to ListActivity:

public class Notepadv1 extends ListActivity

Note: you will have to import ListActivity into the Notepadv1 class using Eclipse, ctrl-shift-O on Windows or Linux, or cmd-shift-O on the Mac (organize imports) will do this for you after you’ve written the above change.

Step 8

Fill out the body of the onCreate() method.

Here we will set the title for the Activity (shown at the top of the screen), use the notepad_list layout we created in XML, set up the NotesDbAdapter instance that will access notes data, and populate the list with the available note titles:

  1. In the onCreate method, call super() with the savedInstanceState parameter that’s passed in.
  2. Call setContentView() and pass R.layout.notepad_list.
  3. At the top of the class, create a new private class field called mDbHelper of class NotesDbAdapter.
  4. Back in the onCreate method, construct a new NotesDbAdapter instance and assign it to the mDbHelper field (pass this into the constructor for DBHelper)
  5. Call the open() method on mDbHelper to open (or create) the database.
  6. Finally, call a new method fillData(), which will get the data and populate the ListView using the helper — we haven’t defined this method yet.

onCreate() should now look like this:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.notepad_list);
        mDbHelper = new NotesDbAdapter(this);
        mDbHelper.open();
        fillData();
    }

And be sure you have the mDbHelper field definition (right under the mNoteNumber definition):

    private NotesDbAdapter mDbHelper;

Step 7

把 Notepadv1的继承类从 Activity改成 ListActivity:
public class Notepadv1 extends ListActivity

注意:你必须通过eclipse导入 ListActivity类到 Notepadv1 类,当你写上以上代码时用 快捷键ctrl-shift-O (win,linux), 或者cmd-shift-O (mac) (组织导入命令)将会为你做这些。

Step 8

研究下onCreate() 方法。

在这里我们要设置 Activity的标题 (显示在屏幕最上面), 用我们在xml文件里创建的notepad_list布局,设置 NotesDbAdapter实例来访问记录数据然后从列表里弹出可用的记录标题 :

  1. onCreate方法里,传入savedInstanceState 参数调用super() 
  2. 输入参数R.layout.notepad_list调用setContentView() 
  3. 在类的最前面,创建了一个私有类字段NotesDbAdapter类 mDbHelper。
  4. 回到onCreate方法,创建一个新的NotesDbAdapter 实例然后把它赋给mDbHelper字段(传递this 到DBHelper的构造器里)
  5. 调用mDbHelper 的open() 方法来打开(或建立)数据库。
  6. 最后调用fillData()方法,将会获得数据并通过这个helper返回listview—我们还没定义这个方法啦

onCreate() 方法完整代码应该是这样滴

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.notepad_list);
        mDbHelper = new NotesDbAdapter(this);
        mDbHelper.open();
        fillData();
    }

确认下你有定义了 mDbHelper字段(正好在 mNoteNumber 的定义下啦):

    private NotesDbAdapter mDbHelper;

Step 9

Fill out the body of the onCreateOptionsMenu() method.

We will now create the “Add Item” button that can be accessed by pressing the menu button on the device. We’ll specify that it occupy the first position in the menu.

  1. In strings.xml resource (under res/values), add a new string named “menu_insert” with its value set to Add Item:
    <string name="menu_insert">Add Item</string>

    Then save the file and return to Notepadv1.

  2. Create a menu position constant at the top of the class:
    public static final int INSERT_ID = Menu.FIRST;
  3. In the onCreateOptionsMenu() method, change the super call so we capture the boolean return as result. We’ll return this value at the end.
  4. Then add the menu item with menu.add().

The whole method should now look like this:

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        boolean result = super.onCreateOptionsMenu(menu);
        menu.add(0, INSERT_ID, 0, R.string.menu_insert);
        return result;
    }

The arguments passed to add() indicate: a group identifier for this menu (none, in this case), a unique ID (defined above), the order of the item (zero indicates no preference), and the resource of the string to use for the item.

 

Step 9

研究下 onCreateOptionsMenu() 方法:

我们现在要创建当按下菜单按钮时显示的 “Add Item” 按钮.我们指定他显示在菜单第一个位置。

  1. strings.xml 资源(在res/values目录下),添加一个字符串”menu_insert”字段同时指定值为 to Add Item:
    <string name="menu_insert">Add Item</string>

    保存文件回到 Notepadv1.

  2. 在类最前面创建一个菜单位置常量:
    public static final int INSERT_ID = Menu.FIRST;
  3. onCreateOptionsMenu() 方法里,改下 super调用,我们就可以获得 boolean 返回值当做结果. 我们将会返回在最后返回这个值。
  4. 然后通过menu.add().方法添加这个菜单项。

整个方法应该是这样滴啦:

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        boolean result = super.onCreateOptionsMenu(menu);
        menu.add(0, INSERT_ID, 0, R.string.menu_insert);
        return result;
    }

传递给add方法的参数说明: a group identifier for this menu (none, in this case), a unique ID (defined above), the order of the item (zero indicates no preference), and the resource of the string to use for the item.

 

Step 10

Fill out the body of the onOptionsItemSelected() method:

This is going to handle our new “Add Note” menu item. When this is selected, the onOptionsItemSelected() method will be called with the item.getId() set toINSERT_ID (the constant we used to identify the menu item). We can detect this, and take the appropriate actions:

  1. The super.onOptionsItemSelected(item) method call goes at the end of this method — we want to catch our events first!
  2. Write a switch statement on item.getItemId().In the case of INSERT_ID, call a new method, createNote(), and return true, because we have handled this event and do not want to propagate it through the system.
  3. Return the result of the superclass’ onOptionsItemSelected() method at the end.

The whole onOptionsItemSelect() method should now look like this:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case INSERT_ID:
            createNote();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

 

Step 10

研究下 onOptionsItemSelected() 方法:

这个是要处理我们的新 “Add Note”菜单项。当这个被选中onOptionsItemSelected() 方法将被item.getId()设置为INSERT_ID (我们用来标识菜单项的常量). 我们可以检测到这个,然后采取适当的动作:

  1.  super.onOptionsItemSelected(item) 方法在这个方法最后调用—我们得捕获我们的事件先!
  2. 在 item.getItemId()写一个 switch 语句.在 INSERT_ID分支,调用一个新方法,createNote(), 然后返回 true, 因为我们已经捕获这个事件,也不需要在返回给系统了。
  3. 在最后返回父类的 onOptionsItemSelected() 方法调用结果

整个 onOptionsItemSelect() 方法大致是这样滴

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case INSERT_ID:
            createNote();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

Step 11

Add a new createNote() method:

In this first version of our application, createNote() is not going to be very useful. We will simply create a new note with a title assigned to it based on a counter (“Note 1″, “Note 2″…) and with an empty body. At present we have no way of editing the contents of a note, so for now we will have to be content making one with some default values:

  1. Construct the name using “Note” and the counter we defined in the class: String noteName = "Note " + mNoteNumber++
  2. Call mDbHelper.createNote() using noteName as the title and "" for the body
  3. Call fillData() to populate the list of notes (inefficient but simple) — we’ll create this method next.

The whole createNote() method should look like this:

    private void createNote() {
        String noteName = "Note " + mNoteNumber++;
        mDbHelper.createNote(noteName, "");
        fillData();
    }

Step 11

添加一个新的createNote()方法: 在我们的应用程序第一个版本, createNote() 不会很有用啦。我们只会简单的创建一个新的记录,记录有个基于计数器的标题("Note 1", "Note 2"...),和空的body 目前我们还没有办法编辑记录的内容, 到目前为止我们 will have to be content making one with some default values(不知道啥):
  1. 用"note"和我们定义在类里的计数器构造名字: String noteName = "Note " + mNoteNumber++
  2. 用noteName和空的body参数调用mDbHelper.createNote()方法
  3. 调用fillData()方法来弹出记录列表 (效率低但很简单啦) — 我们等下会建立这个方法。
整个 createNote() 方法大概是这样滴:
    private void createNote() {
        String noteName = "Note " + mNoteNumber++;
        mDbHelper.createNote(noteName, "");
        fillData();
    }

Step 12

Define the fillData() method:

This method uses SimpleCursorAdapter, which takes a database Cursor and binds it to fields provided in the layout. These fields define the row elements of our list (in this case we use the text1 field in our notes_row.xmllayout), so this allows us to easily populate the list with entries from our database.

To do this we have to provide a mapping from the title field in the returned Cursor, to our text1 TextView, which is done by defining two arrays: the first a string array with the list of columns to map from (just “title” in this case, from the constant NotesDbAdapter.KEY_TITLE) and, the second, an int array containing references to the views that we’ll bind the data into (the R.id.text1 TextView).

This is a bigger chunk of code, so let’s first take a look at it:

    private void fillData() {
        // Get all of the notes from the database and create the item list
        Cursor c = mDbHelper.fetchAllNotes();
        startManagingCursor(c);

        String[] from = new String[] { NotesDbAdapter.KEY_TITLE };
        int[] to = new int[] { R.id.text1 };

        // Now create an array adapter and set it to display using our row
        SimpleCursorAdapter notes =
            new SimpleCursorAdapter(this, R.layout.notes_row, c, from, to);
        setListAdapter(notes);
    }

Here’s what we’ve done:

  1. After obtaining the Cursor from mDbHelper.fetchAllNotes(), we use an Activity method called startManagingCursor() that allows Android to take care of the Cursor lifecycle instead of us needing to worry about it. (We will cover the implications of the lifecycle in exercise 3, but for now just know that this allows Android to do some of our resource management work for us.)
  2. Then we create a string array in which we declare the column(s) we want (just the title, in this case), and an int array that defines the View(s) to which we’d like to bind the columns (these should be in order, respective to the string array, but here we only have one for each).
  3. Next is the SimpleCursorAdapter instantiation. Like many classes in Android, the SimpleCursorAdapter needs a Context in order to do its work, so we pass in this for the context (since subclasses of Activity implement Context). We pass the notes_row View we created as the receptacle for the data, the Cursor we just created, and then our arrays.

In the future, remember that the mapping between the from columns and to resources is done using the respective ordering of the two arrays. If we had more columns we wanted to bind, and more Views to bind them in to, we would specify them in order, for example we might use { NotesDbAdapter.KEY_TITLE, NotesDbAdapter.KEY_BODY } and { R.id.text1, R.id.text2 } to bind two fields into the row (and we would also need to define text2 in the notes_row.xml, for the body text). This is how you can bind multiple fields into a single row (and get a custom row layout as well).

If you get compiler errors about classes not being found, ctrl-shift-O or (cmd-shift-O on the mac) to organize imports.

 

Step 12

定义 fillData() 方法:

这个方法使用 SimpleCursorAdapter,传入一个数据库指针参数,然后绑定他到layout里提供的字段里. 这些字段定义行元素到我们的list里(在这个例子里我们使用在 notes_row.xml 布局里的text1字段), 所以这允许我们很容易的获得数据库里的含有实体的list。

为了做这个我们需要提供一个在返回的指针里title字段的映射到我们的 text1 TextView, 定义2个数组来完成他: 第一个是一个列映射list的字符串数组(在这里只有”title”, 来自常量NotesDbAdapter.KEY_TITLE) ,第二个,是一个整数数组包含views的引用,我们将会绑定数据到这个引用(R.id.text1 TextView).

这里有比较多的代码,所以我们一起来分析下:

    private void fillData() {
        // Get all of the notes from the database and create the item list
        Cursor c = mDbHelper.fetchAllNotes();
        startManagingCursor(c);

        String[] from = new String[] { NotesDbAdapter.KEY_TITLE };
        int[] to = new int[] { R.id.text1 };

        // Now create an array adapter and set it to display using our row
        SimpleCursorAdapter notes =
            new SimpleCursorAdapter(this, R.layout.notes_row, c, from, to);
        setListAdapter(notes);
    }

在上面的代码里,我们做了这些事啦:

  1. 在我们获得来自 mDbHelper.fetchAllNotes()的指针后,我们调用一个activity方法startManagingCursor()来使得Android 处理这个指针的生命周期这样我们就不要担心他咯~。 (我们会在练习3里谈到这个生命周期的具体实现, 我们现在只要知道这会使得Android为我们做一些资源管理的事就够了)
  2. 然后我们创建一个我们声明需要的列(在这里,只有title啦)字符串数组, 和一个定义了我们想要绑定到列上的view整数数组(这将会按照各自的字符串数组按顺序排列,不过我们现在只有一个啦).
  3. 下一步就是 SimpleCursorAdapter 实例.和大多数Android里的类类似,SimpleCursorAdapter 需要一个context来让他运行, 所以我们传入了 this (因为activity的子类实现了 Context).我们传入 notes_row 视图,指针,和我们的数组。

将来,一定要记住各自从列到资源的映射的顺序。如果我们有更多的列要绑定,也同时要有更多的view绑定到to里,我们按顺序指定他们,比如我们可能会用{ NotesDbAdapter.KEY_TITLE, NotesDbAdapter.KEY_BODY } 和{ R.id.text1, R.id.text2 } 来绑定2个字段到行里 (当然我们也得为body文本在 notes_row.xml里定义text2 ).这就是你如何绑定多字段数据到一个行里(同时也使用一个定制的layout)方法。

如果你有类未找到的编译错误,使用 ctrl-shift-O or (cmd-shift-O on the mac) 来组织导入。

 

Step 13

Run it!

  1. Right click on the Notepadv1 project.
  2. From the popup menu, select Run As > Android Application.
  3. If you see a dialog come up, select Android Launcher as the way of running the application (you can also use the link near the top of the dialog to set this as your default for the workspace; this is recommended as it will stop the plugin from asking you this every time).
  4. Add new notes by hitting the menu button and selecting Add Item from the menu.

Solution and Next Steps

You can see the solution to this class in Notepadv1Solution from the zip file to compare with your own.

Once you are ready, move on to Tutorial Exercise 2 to add the ability to create, edit and delete notes.

Step 13

运行它咯!

  1. 右击 Notepadv1 项目。
  2. 选择 Run As > Android Application.
  3. 如果你看到一个对话框出现,选择 Android Launcher作为运行这个应用程序的方法(你也可以使用在对话框最顶端的链接来设置这个作为你的默认工作空间,这样插件就不会每次都这样问你了).
  4. 通过点击菜单按钮并选择添加选项来添加新的记录。

Solution and Next Steps

你可以在Notepadv1Solution 看到这个类的答案

当你都搞定了,你就可以到下一个练习了,来添加创建编辑和删除记录的功能了。


Bookmark and Share

教程:一个记事本应用程序范例

This item was filled under [ 一步一步学习 ]

 

本教程通过手把手教你的方式, 讲解如何利用Android框架和诸多工具建立自己的手机应用。从一个预配置好的工程文件开始,该教程通过一个简单的记事本应用程序开发的完整过程,并辅以贯穿始终的详尽例子,指导你如何建立工程、组织应用逻辑以及UI,乃至接下来的编译及运行程序等等。

该教程将这个记事本应用的开发过程视作一组练习(见如下),每一个练习都由若干步骤组成。你可以亦步亦趋地完成每个练习步骤,逐步建立并完善自己的应用程序。这些练习提供了你实现此应用所需的——细到每一步骤的——具体范例代码。

当你完成此教程后,一个具有实际功能的Android应用就从你手上诞生了,并且你对Android应用开发中的一些极为重要的概念也有了更深入的理解。若你想为你这个简单的记事本应用添加更多复杂功能的话,你可以用另一方式实现的记事本程序比照你的代码,具体可参看 Sample Code 文档部分。

本教程目标读者

该教程主要是面向有一定经验的开发者,尤其是那些具备一定Java编程语言知识的。如果你之前从未写过一个Java应用的话,仍可以使用此教程,只是学习进度稍稍慢一点罢了。

本教程假定你已熟悉了一些基本的Android应用概念和术语。如果你对这些还不够熟稔的话,你得将 Overview of an Android Application 好好温故一下,才能继续下面的学习。

同时需注意的时,该教程的集成开发环境是预装Android插件的Eclipse。如果你不用Eclipse,仍可做下面的这些练习和建立应用,但你届时将不得不面对一些涉及Eclipse的步骤在非Eclipse IDE中如何实现的问题。

练习前的准备

有关此教程中涉及建立Android应用的相关信息已在Installing the SDK 和 Hello Android 这两份文档中有详细说明了。这两份文档详细地解释了为建立Android应用,搭建自己的开发环境所必需的知识。在你开始学习本教程之前,两份文档、SDK安装以及开发环境搭建你得确保都已万事俱备,只欠东风了。

为此节训练所需的准备工作: project exercises archive (.zip) 2.解压至你本地的某一目录下 3.打开NotepadCodeLab文件夹

  1. 下载 project exercises archive (.zip)
  2. 解压至你本地的某一目录下
  3. 打开 NotepadCodeLab 文件夹

NotepadCodeLab 这一文件夹下共有六个工程文件,具体分别是:Notepadv1, Notepadv2, Notepadv3, Notepadv1Solution, Notepadv2Solution 和 Notepadv3Solution。其中诸如Notepadv#的工程目录是每个练习的起点,而Notepadv#Solution则是对应的答案。如果你在某一练习中遇到问题,你可以将你本地工程的代码与练习的答案对比一下找到答案。

练习

下表列出了本教程的一些练习,并描述每一练习所涵盖的开发内容。每一练习都是基于你已完成之前的任一练习这一前提来展开的。

练习 1 一个简单记事本应用程序的开发过程起始于此。构建一个可以添加新记事内容,但不能编辑的简单记事列表。演示ListActivity 的基本方面以及如何创建和控制菜单项,以及用一个SQLite数据库存储记事内容。
练习 2 为记事本应用程序添加第二个Activity。演示如何构造一个新Activity至Android,在不同Activity之间传输数据,使用更多高级的屏幕布局。并演示如何通过调用startActivityForResult()这个API来激活另一窗口并返回一个结果。
练习 3 为应用添加对事件生命周期的控制,以保持应用程序在整个生命周期中的定义。
额外学习 演示如何使用Eclipse的调试器及通过调试器查看事件产生后的整个生命周期。此节非必读,但仍极力推荐一读。

其它资源及延伸学习

  • 对本教程未涉及的一些轻微但更广博的概念请参阅 Common Android Tasks.
  • Android SDK已包含了适合进一步学习,功能完整的绝佳范例。具体范例可以在你下载的SDK中的samples目录中找到。
  • 尽管与SDK samples 目录下的完整记事本应用程序并非完全一致,但这一教程还是脱胎于此。当你学习本教程时,强烈建议你仔细看看SDK Sample目录下的记事本应用程序。其中包含了一些较之个人学习应用程序中更为有趣的附加信息,诸如:
    • 建立一个有条纹的自定义记事列表
    • 创建一个自定义的文本编辑窗口,该窗口覆写 draw() 方法,使其看起来像一个真正的有下划线的便笺记事本
    • 一个完整的ContentProvider实现
    • 撤销和放弃编辑操作而非自动保存该编辑操作的结果
Bookmark and Share

Android 应用程序构成

This item was filled under [ 一步一步学习 ]

一般情况Android应用程序是由以下四种组件构造而成的:

  • Activity
  • Broadcast Intent Receiver
  • Service
  • Content Provider

需要注意的是,并不是每个Andorid应用程序都必须构建这4个组件,有些可能由这4个组件的组合而成。

一旦你确定了你的应用程序中需要的组件,那么你就应该在AndroidManifest.xml中列出他们。 这是一个XML配置文件,它用于定义应用程序中需要的组件、组件的功能及必要条件等。这个文件是必须的。 详情参见Android manifest file documentation 

四种组件说明如下:

Activity

Activity是最基本的Andorid应用程序组件,应用程序中,一个activity就是一个单独的屏幕。每一个activity都被实现为一个独立的类,并且从Activity基类中继承而来, activity类将会显示由Views控件组成的用户接,并对事件做出响应。 大多数的应用是由多屏幕显示组成。例如,一个文本信息的应用也许有一个显示发送消息的联系人列表屏幕, 第二个屏幕用来写文本消息和选择收件人, 再来一个屏幕查看消息历史或者消息设置操作等。这里每一个这样的屏幕就是一个activity,很容易实现从一个屏幕到一个新的屏幕并且完成新的activity。 在某些情况下当前的屏幕也许需要向上一个屏幕动提供返回值–比如让用户从手机中挑选一张照片返回通讯录做为电话拨入者的头像。

当打开一个新的屏幕时,之前一个屏幕会被置为暂停状态并且压入历史堆栈中。用户可以通过回退操回到以前打开过的屏幕。我们可以选择性的移除一些没有必要保留的屏幕,因为Android会把每个应用的开始到当前的每一个屏幕保存在堆栈中。

Intent 和 Intent Filters

调用Android专有类 Intent 进行构屏幕之间的切换。 Intent是描述应用想要做什么。Intent两最重要的部分是Intent结构数据的动作和动作对应的数据。 典型的动作类型有:MAIN(activity的门户)、VIEW、PICK、EDIT等。 而动作对应的数据则以URI的形式进行表示。 例如:要查看某一个人的联系方式,你需要创建一个动作类型为VIEW的intent,以及一个表示这个人的URI。

与之有关系的一个类叫IntentFilter。 相对于intent是一个有效的做某事的请求,一个intent filter则用于描述一个activity(或者Intent Receiver,看下面)能够操作哪些intent。 一个activity如果要显示一个人的联系方式时,需要声明一个IntentFilter,这个IntentFilter要知道怎么去处理VIEW动作和表示一个人的URI。 IntentFilter需要在AndroidManifest.xml中定义。

通过解析各种intent,从一个屏幕导航到另一个屏幕是很简单的。当向前导航时,activity将会调用startActivity(myIntent)方法。 然后,系统会在所有安装的应用程序中定义的IntentFilter中查找,找到最匹配myIntent的Intent对应的activity。新的activity接收到myIntent的通知后,开始运行。 当startActivity方法被调用将触发解析myIntent的动作,这个机制提供了两个关键好处:

  • Activities能够重复利用从其它组件中以Intent的形式产生的一个请求
  • Activities可以在任何时候被一个具有相同IntentFilter的新的Activity取代

Broadcast Intent Receiver

你可以使用BroadcastReceiver来让你的应用对一个外部的事件做出响应。 比如:当电话呼入时,数据网络可用时,或者到了晚上时。BroadcastReceivers不能生成UI,它只能通过 NotificationManager 来通知用户这些可能算是有趣的事情发生了。BroadcastReceivers既可以实现在AndroidManifest.xml中注册, 也可以在运行时的代码中使用Context.registerReceiver()进行注册。 但这些有趣的事情发生时,你的应用不必对请求调用BroadcastReceivers,系统会在需要的时候启动你的应用,并在必要情况下触发BroadcastReceivers。 各种应用还可以通过使用Context.sendBroadcast() 将它们自己的intent broadcasts广播给其它应用程序。

Service

一个Service是具有一段较长生命周期且没有用户界面的程序。 比较好的一个例子就是一个正在从播放列表中播放歌曲的媒体播放器。在一个媒体播放器的应用中,应该会有多个activity,让使用者可以选择歌曲并播放歌曲。 然而,音乐重放这个功能并没有对应的activity,因为使用者当然会认为在导航到其它屏幕时音乐应该还在播放的。 在这个例子中,媒体播放器这个activity会使用Context.startService() 来启动一个service,从而可以在后台保持音乐的播放。 同时,系统也将保持这个service一直执行,直到这个service运行结束。(你可以通过阅读Life Cycle of an Android Application 获取更多关于services的介绍). 另外,我们还可以通过使用Context.bindService() 方法,连接到一个service上(如果这个service还没有运行将启动它)。 当连接到一个service之后,我们还可以service提供的接口与它进行通讯。拿媒体播放器这个例子来说,我们还可以进行暂停、重播等操作。

Content Provider

应用程序能够将它们的数据保存到文件中、SQLite数据库中,甚至是任何有效的设备中。当你想将你的应用数据与其它的应用共享时,Content Provider将会很有用。一个Content Provider类实现了一组标准的方法,从而能够让其它的应用保存或读取此Content Provider处理的各种数据类型。 更详细的Content Provider资料,可以参考附带文档中的Accessing Content Providers。

更详细的Content Provider资料,可以参考附带文档中的 Accessing Content Providers

Bookmark and Share

Hello, Android!

This item was filled under [ 一步一步学习 ]

作为开发者,你的第一感觉是你拿到这个开发框架写“Hello, World!”程序时的难易程度给你留下的。 当然,在Android里,这个非常容易,下面我给你演示:

创建工程

创建一个尽可能简单的工程,Eclipse的插件可以使Android的开发变得简单。

你需要一台装有 Eclipse IDE (参考 系统和软件需求的电脑你还需要安装 Android Eclipse 插件 (ADT)如果你都准备好了继续看这里。

首先,你需要对如何创建“Hello, World!”有个大概的了解:

1.  在菜单 File > New > Project 中创建一个新的Android 项目.

2.  在创建Android项目的对话框里填写项目的详细信息。

3.  编辑自动生成代码的模板去显示一些输出。

这样就可以了,下一步,我们将详细讲解每一步。

 

1.    创建一个新的Android项目

打开Eclipse, 选择 File->New->Project menu item. 如果AndroidEclipse的插件正确安装了,弹出的对话框里就会有一项“Android”,这一项有唯一的子项 Android Project”。

选中“Android Project”,点下一步。

2.    填写工程的详细信息

   下一步需要你填写项目的详细信息,这里有个例子:

每一项具体的意思:

工程名

你想把工程保存在你机器上哪个目录里

包名

包的命名空间(需要遵循java编程语言的命名规则),你的所有代码都会在这个命名空间下。这也会生成包的名称从而活动自动生成。

你使用的这个包的名字必须和其他安装在你机器上的包名字不冲突,所以,使用一个标准规则的包名字是非常重要的。如上例,我们使用包的名字为“com.android但你需要使用一个不同的类型。

“活动”名

这是插件为你自动生成类的名字.它也会是Android活动类的一个子类。一个活动仅仅是一个包含一些功能并能执行的类。如果它选择,可以创建用户界面,但这不是必须的.

程序名

这是最后生成应用程序的名字。

可选框里“Use default location” 允许你选择其他目录保存项目产生的其它文件。

3.    编辑自动生成代码

运行插件后,会自动生成一个类“HelloAndroid (可以在程序包里 HelloAndroid > src > com.android.hello找到). 像这样:

public class HelloAndroid extends Activity {

    /**活动第一次被创建后调用.*/

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

    }

}

现在,你可以执行程序了。不过我们还可以进一步研究下,这样我们能更好得理解程序。所以,下一步我们可以改一些代码!

建立UI

看下面我们修改的代码,你可以在你的HelloAndroid.java文件里做相同的修改,我们来逐行分析:

package com.android.hello;

import android.app.Activity;

import android.os.Bundle;

import android.widget.TextView;

public class HelloAndroid extends Activity {

   /**活动第一次被创建后调用.*/

   @Override

   public void onCreate(Bundle savedInstanceState) {

       super.onCreate(savedInstanceState);

       TextView tv = new TextView(this);

       tv.setText(“Hello, Android”);

       setContentView(tv);

   }

}

小提示: 如果你忘记引入 TextView的包,可以尝试按Ctrl-Shift-O(如果是Mac系统Cmd-Shift-O) 这是Eclipse管理应用的快捷方式-它会显示没有找到的包然后自动为你加上。

Android里,用户接口由一些称之为视图的不同层次的类组成。 一个视图就是一个简单的对象。如单选框,动画控件,一个文本框(我们的例子里的),我们称处理文本的这样一个子视图就叫TextView

这里教你如何创建 TextView

TextView tv = new TextView(this);

TextView构造器就是Android上下文的实例,这个上下文仅仅是指向系统的一个句柄,它提供像资源处理之类的服务。包含一些进入资料库以及参数选择的入口。这个活动也是继承上下文。 HelloAndroid类是活动的一个子类,它也是一个上下文,我们能通过this操作TextView.

  创建TextView后,加入需要显示的内容:

tv.setText(“Hello, Android”);

这很正常:

我们创建一个TextView,然后告诉它显示的内容。最后一步就是让TextView在屏幕上显示出来,像这样:

setContentView(tv);

活动里setContentView()的方法表明哪个视图需要在当前UI上被操作。如果一个活动不能调用这个方法,那么当前就没有界面系统显示为一个空白屏幕。我们仅仅想显示一些文本,所以我们将刚才创建的TextView连接上。

这就是Android平台里的“HelloWorld”,当然,我们可以看下运行情况。

执行代码:HelloAndroid

Eclipse的插件使得你的程序很容易运行。选择Run->Open Run Dialog菜单。(Eclipse3.4版本中,菜单为Run->Run Configurations)可以看到这样的对话框:

下一步,选择“Android Application”,点击在左上角(按钮像一张纸上有个“+”号)或者双击“Android Application”。 有个新的选项“New_configuration”。

将名字改得更形象一点,如“HelloAndroid”,然后按Browse按钮选择你的项目,(如果你Eclipse里有多个Android项目需要打开,确定要选择正确)插件会会自动扫描你项目里的活动子类,然后在“活动”的下拉菜单里加载。如果你的“HelloAndroid”项目只有一个,它将被设置为默认项目,然后你可以继续:

点击“Apply”按钮,这里有个例子:

这样就可以了,点击“Run”按钮,Android的模拟器启动。一启动你的程序就会出现,当一切OK,你可以看到:

这就是Android的“Hello, World”,是不是非常简单呢?下一章节我们将提供更详细的信息。当你接触更多的Android时,你会发现它非常有价值。

使用XML构建UI

你刚刚完成的“Hello, World”的例子使用的是我们称为“可编程”的UI层,意思是你通过编写代码来组建UI层。当你开发了足够多的UI程序,你会发现一些很糟糕的现象: 一些小的变化需要你做大量的代码改动。你常常会忘记将View连接起来,这样会导致一些错误,浪费你很多时间去调试代码。

这就是Android为什么提供一个可变化的UI开发模块:基于XML的文件。最简单解释这个概念就是演示个例子。这里有个XML的文件,它能达到和你刚才完成代码同样的效果:

<?xml version=”1.0″ encoding=”utf-8″?>

<TextView xmlns:android=”http://schemas.android.com/apk/res/android”

  android:layout_width=”fill_parent”

  android:layout_height=”fill_parent”

  android:text=”Hello, Android”/>

通常AndroidXML文件结构是很简单的。只是一些标记的树形集合,每个标记就是一个视图类。在这个例子中,它就是一个简单的TextView元素的树,你可以在XML文件里使用任何扩展类的名字作为你的标记,这也包括你在你的自己的代码里定义的名字。这个结构使得你能使用简单结构和语法快速的组建UI,这种模型就像网站的开发模型,你能够将UI和程序逻辑分开,单独获取或者填充数据。

在这个例子里,有4XML属性,下面是属性的大概意思:

属性

描述

xmlns:android

这是一个XML命名空间,告诉Android开发工具你准备使用Android命名空间里的一些通用属性。在所有Android XML设计文件中最外层的标记必须使用这个树形。

android:layout_width

这个属性定义了这个视图需要占用的屏幕宽度。在这个例子中,我们仅有的一个视图可以占用整个屏幕,那就是“fill_parent”的意思。

android:layout_height

这个和“layout_width”差不多,表示占用屏幕的高度。

android:text

这个设置文本显示内容,在这个例子里,我们使用“HelloAndroid”。

这就是XML的布局,你需要把这个文件放在什么位置? 放在你的工程/res/layout下就可以。“res”是“resource”的简称,这个目录包含了所有应用程序需要的非代码部分。比如图片,字符串,XML文件。

Eclipse插件为你创建了这些XML文件中的一个。在我们上面的范例,我们根本没有使用过它。在包的管理器里,展开目录/res/layout,编辑main.xml文件,替换上面的文本然后保存修改。

现在从代码目录里打开 R.java文件,你可以看到他们像这样:

 

public final class R {

    public static final class attr {

    };

    public static final class drawable {

        public static final int icon=0×7f020000;

    };

    public static final class layout {

        public static final int main=0×7f030000;

    };

    public static final class string {

        public static final int app_name=0×7f040000;

    };

};

R.java是文件中所有资源的索引界定值定义。你在代码中使用这个类,就像在你的项目里使用一个简洁的方法表示你的资源。在Eclipse这样的IDE工具里,这个方式对于代码自动完成功能还是非常有效的,因为这能让你快速得定位你要寻找的东西。

有个重要点需要注意的是有个内部类“layout,是“main”的成员类。Eclipse插件提醒你加了一个新的XML文件,然后生成R.java文件,当你加入其他资源到你的工程里,你可以看到R.java在同步更改。

最后要做的就是使用你最新版本的XML修改你的HelloAndroid代码去代替以前的编码。 这个有例子说明重新写过的类的模型,你可以看到,代码变得非常简单。

package com.android.hello;

import android.app.Activity;

import android.os.Bundle;

public class HelloAndroid extends Activity {

    /**活动第一次被创建后调用. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

    }

}

当你做这些修改的时,你只需要拷贝,复制。在那个R的类里你可以使用代码自动完成功能,你会发现那确实很有帮助。

现在你已经完成了这些修改,继续执行你的程序-你需要做的就是按下绿色的“Run”按钮,或者在菜单中选择Run->Run History->Hello,Android. 你可以看到… 哇哦,和之前看到的一样!这点表明两种不同的构建方式都能达到同样的结果。

还有很多方法去创建XML文件,在你想做之前,读一下“实现用户接口”可以获得更多信息。

调试工程

AndroidEclipse开发的插件和Eclipse的调试工具结合得也很好为了演示一下,我们在代码里加入一个bug。你可以像下面的代码一样修改你的代码:

package com.android.hello;

import android.app.Activity;

import android.os.Bundle;

public class HelloAndroid extends Activity {

    /**活动第一次被创建后调用.*/

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        Object o = null;

        o.toString();

        setContentView(R.layout.main);

    }

}

这个修改仅仅引入了一个NullPointerException到你的代码里。 如果你再次运行程序,最后你会看到:

按“Force Quit”终止程序并关掉模拟器窗口。

为了寻找错误的原因,设置一个断点在“Object o = null(在代码行旁边的标记栏双击); 然后从菜单选择Run->Debug History->Hello,Android进入调试模式。你的应用程序会在模拟器里重新启动,但这次会在你设的断点处停住。 你可以在Eclipse’s Debug Perspective里单步执行代码,就像你调试其他程序一样。

不使用Eclipse创建工程

如果你不使用Eclipse(比如你喜欢其他IDE工具,或者仅仅使用文本编辑器或者命令行工具),那么Eclipse的插件对你没有作用。别担心-它不会因为你不使用Eclipse而使用失去任何功能。

AndroidEclipse的插件仅仅是Android SDK外围的一个工具。(这些工具如: 模拟器,aapt, adb, ddms等等都在 其他文档因此,将这些工具和其他工具如“ant”编译文件结合也是有可能的。

Android SDK里包含一个Python的脚本“activitycreator.py,它可以为你的项目创建所有的代码以及目录。就像ant中的“build.xml”文件。这允许你使用命令行编译你的工程或者使用你自己的IDE工具集成。

例如,就像我们刚使用Eclipse创建的HelloAndroid项目,你可以使用命令:

activitycreator.py –out HelloAndroid com.android.hello.HelloAndroid

编译工程的时候,你运行“ant”命令,当命令成功执行后,将在“bin”目录里产生一个 HelloAndroid.apk”的文件,“apk”文件是Android的一个包,你可以使用“adb”工具安装或者执行。

如果想获得更多信息,请阅读网站提供的替他文档。

Bookmark and Share

开发和调试

This item was filled under [ 一步一步学习 ]

这一节将介绍在android上开发调试应用程序。它将教会我们如何创建,编译,运行以及调试android代码。或者,你也可以从Hello Android tutorial.开始

 

在eclipse上开发Android应用程序

在用eclipse IDE开发android应用程序之前,你首先要创建一个Android工程,并且建立一个启动配置,在此之后你才可以开始编写,运行,以及调试你的应用程序。

以下章节是假设你已经在eclipse环境中安装了ADT插件,如果你没有安装,请安装之后再使用以下说明。参考 安装eclipse 插件(ADT)

创建一个android工程

ADT提供了一个新的工程向导,你可以快速的创建一个新的工程或者在现有代码上创建工程。创建工程的步骤如下:

选择File > New > Project

  1. 选择 Android > Android Project, 然后按下 Next
  2. 选择项目内容:
    • 选择 Create new project in workspace, 为编码创建一个全新的工程。输入工程名称(project name),基础软件包的名称(the base package name),以及Activity 类的名称。以创建stub .java文件等文件和程序名字。
    • 选择Create project from existing source ,为已有代码创建一个工程。如果你想编译运行SDK中提供的示例程序,可以使用这个选项。示例程序的存放在SDK的samples/目录下。浏览包含已有代码的目录,点击ok,如果目录中包含有可用的android manifest 文件,ADT将为你填写合适的软件包,activity,和应用程序名称。
  3. 按下Finish.

ADT插件会根据你的工程类型创建合适的文件和文件夹,如下:

  • src/   包含stub .java Activity文件的文件夹.
  • res/   资源文件夹.
  • AndroidManifest.xml   工程清单.

 

创建一个启动项

能够在eclipse上运行调试应用程序之前,你必须为它创建一个启动项。启动项指定哪个工程将被启动,哪个activity开始工作,以及使用哪些模拟器选项等。

按照以下步骤为Eclipse版本的应用程序创建合适的启动项:

  1. 打开启动项管理工具。
    • 在 Eclipse 3.3 (Europa)的版本中,酌情选择 Run Open Run Dialog… or Run Open Debug Dialog… 
    • 在Eclipse 3.4 (Ganymede)版本中,酌情选择 Run Run Configurations… or Run Debug Configurations… 
  2. 在左边的工程类型列表选择Android Application选择,双击(或者点击右键选择new),创建一个新的启动项。
  3. 输入启动项名称。
  4. 在 Android标签中,浏览要开始的工程和Activity 。
  5. 在Target标签中,设置想要显示的屏幕及网络属性,以及其他任何模拟器启动选项
  6. 你可以在Common标签中设置更多的选项.
  7. 按下Apply保存启动配置,或者按下Run或Debug()。

 

运行和调试应用程序

一旦你设定了工程和工程启动配置,你就可以按照以下的说明运行和调试应用程序了。

从eclipse主菜单,根据情况选择Run>Run 或者 Run>Debug,开始运行或者调试活动启动项。

注意,这里活动启动项是在运行配置管理中最最近一次选中的那个。它不一定就是在Eclipse Navigation 面板中选择的程序(如果有的话)

设置和修改活动启动项,可以使用启动项管理工具。如何获得启动项管理工具可以参考创建一个启动项

运行或调试应用程序将触发以下动作:

  • 启动模拟器,如果他还没有开始运行。
  • 编译工程, 如果在上次编译的基础上修改过代码,将重新编译。在模拟器上安装应用程序。
  • Run选项,开始运行程序。
  • Debug 在”Wait for debugger “模式下启动程序,然后打开调试窗口并将Eclipse Java调试器和程序关联。

利用其他IDEs和工具开发Android应用程序

通常我们使用安装有ADT插件的eclipse Eclipse with the ADT plugin.来开发Android程序,这个插件将编辑,build和调试功能集成到IDE上。

然而,如果你想在其他的IDE上开发程序,例如IntelliJ,或者使用没有ADT插件的eclipse也可以。SDK提供了安装,编译,调试应用程序所需要的工具。

创建一个android工程

Android SDK包含一个activityCreator的程序,它将为工程产生多个stub文件和一个build文件。你可以用这个程序创建一个新的Android工程或者在现有代码上创建工程,如SDK中包含的例子。对于Linux 和Mac系统,SDK提供activityCreator.py,一个 Python脚本,Windows上则是activityCreator.bat一个批处理脚本。无论是哪种平台,用法是一样的。

按以下步骤运行activityCreator创建Android工程:

  1. 在命令行下,切换到SDK下的tools/目录下,为你的工程文件新建一个目录。如果你是在现有代码上创建工程,切换到程序的根目录下。
  2. 运行activityCreator。在命令行下,你必须指定完全合格的类名作为参数。如果你是创建一个全新的工程,这个类代表的与它同名的stub类和脚本文件。如果是在现有代码上创建工程,必须指定软件包中其中一个Activity类的名称。 命令选项的脚本包括:
    • --out <folder> 设定输出目录。默认情况下输出目录为当前目录。如果你想为工程文件创建一个新的目录,可以使用这个选项来指向它。
    • --ide intellij, 在一个新的项目中生成IntelliJ IDEA 工程文件。

这里有个例子:

~/android_linux_sdk/tools $ ./activityCreator.py --out myproject your.package.name.ActivityName
package: your.package.name
out_dir: myproject
activity_name: ActivityName
~/android_linux_sdk/tools $

activityCreator脚本生成以下文件和目录(但是不能重写已有文件):

  • AndroidManifest.xml 程序的清单文件,同时为工程指定Activity类。
  • build.xml 一个Ant文件,用来编译/打包应用程序。
  • src/your/package/name/ActivityName.java 你指定的输入Activity类。
  • your_activity.iml, your_activity.ipr, your_activity.iws    [only with the -ide intelliJ flag] intelliJ工程文件
  • res/   资源目录.
  • src/    源代码目录.
  • bin/    build脚本的输出目录.

现在你可以将开发文件夹移到任何地方,但是记住,必须使用tool/文件夹下的adb程序将文件发送到模拟器上。因此你需要在你工作环境和tools/文件夹之间活动。

当然你需要避免移动SDK目录,因为它将打断编译脚本。(再重新build之前需要手动更新SDK的映射路径)

 

编译 android应用程序

使用activityCreator生成的Ant文件build.xml来编译程序

  1. 如果你没有,你可以通过Apache Ant home page得到Ant文件。安装它,并确定它在你的可执行文件路径下。
  2. 呼叫Ant之前,你需声明JAVA_HOME环境变量,并将它设置为JDK的安装路径。
  3. 注意:在windows上,JDK默认的安装路径为”Program Files”,这个路径将会引起Ant失败,因为路径中间有空格。解决这个问题,你可以像这样指定环境变量JAVA_HOME:JAVA_HOME=c:\Prora~1\Java\ 然而简单的解决方法是将JDK安装在没有空格的目录下。例如:c:\java\jdk1.6.0_02. 

  4. 如果你还没有这么准备好,按照上面创建一个新的工程的介绍建立一个工程。
  5. 现在你可以为你的工程运行Ant编译文件,只需在build.xml同文件夹下输入ant即可。每次修改原文件或是资源,都需要重新运行ant,它将把最新版的应用程序打包以便deploy.

 

运行Android程序

运行一个编译好的程序,你需要用adb工具将.apk文件加载到模拟器的/data/app/目录下,用法如下面介绍。

  1. 启动模拟器(命令行下运行sdk目录下的/tools/emulator)。
  2. 模拟器切换到主画面(最好不要在程序运行的时候向模拟器安装程序,可以按home键离开应用程序)。
  3. 运行adb,安装myproject/bin./<appname>.apk文件。例如,安装Lunar Lander 示例,命令行下,切换到SDK目录下的/sample/LunarLander子目录下,输入../../tools/adb install bin/LunarLander.apk
  4. 在模拟器中,打开可执行程序列表,卷动屏幕,选中并启动你的应用程序。

注意:当你第一次安装一个Activity时,你可能需要在启动项显示之前,或者其它程序调用它之前重新启动模拟器。因为软件包管理工具通常只有在模拟器启动时才能完全的审查manifests。

 

为程序附加调试器

这一节我们介绍如何在屏幕上显示调试信息(例如CPU使用率),以及如何将IDE和模拟器上运行的程序关联起来。

使用eclipse插件可以自动的生成调试器。但你也可以通过配置IDES来监听调试端口得到调试信息。

  1. 启动Dalvik Debug Monitor Server (DDMS) 工具 ,它在IDE和模拟器之间扮演着端口转换服务的角色。?
  2. 设置模拟器调试配置选项。例如,等到调试信息被加载后才启动应用程序。注意,很多调试选项无需DDMS也可以使用,例如模拟器上显示CPU的使用效率,或者屏幕的刷新频率。
  3. 配置IDE,使得调试时IDE与8700端口关联 .how to set up Eclipse to debug your project. 包含以下信息。

 

配置IDE附加调试端口

DDMS将为每一个虚拟机分配一个特殊的调试端口,这个端口在模拟器上可以找到。你必须将你的IDE与此端口(虚拟机上信息栏中有列出这些端口)关联或者是默认的端口8700。这样可以使IDE 连接到模拟器上程序列表中的任一个程序。

你的IDE需要能够关联模拟器上正在运行的程序,显示它的线程,并允许你挂起它,检查它的状态,设置断点。如果你在开发设置面板选择了“等待调试”,应用程序将等到Eclipse连接后才运行,所以你需要在连接之前设置断点。

修改正在调试的程序,或者在当前程序运行时选择“等待调试”将引起系统杀死这个应用程序。如果你的程序处于一种坏的状态,你可以使用方式杀死它,方法很简单,只需要设置和钩掉复选框。

应用程序签名

Android系统要求所有的程序经过数字签名才能安装,如果没有可用的数字签名,系统将不许安装运行此程序。不管是模拟器还是真实设备,只要是android系统,这都适用。鉴于此原因,在设备或者是模拟器上运行调试程序之前,你必须为你的应用程序设置数字签名。

理解android程序签名的重要几点::

  • 所有的程序都必须签名,没有被签名的程序,系统将不能安装。
  • 你可使用自签署证书签署你的应用程序,必须是无凭证授权是的。
  • 系统仅仅会在安装的时候测试签名证书的有效期,如果应用程序的签名是在安装之后才到期,那么应用程序仍然可以正常启用。
  • 你可以使用标准工具-Keytool and Jarsigner-生成密钥,来签名应用程序的.apk文件。

Android SDK 工具可以帮助你在调试时给应用程序签名。ADT插件和Ant编译工具都提供了两种签名模式-debug模式和release模式

  • debug模式下,编译工具使用JDK中的通用程序Keytool通过已知方法和密码创建秘锁和密钥。每次编译的时候,工具使用debug密钥签名应用程序的.apk文件。因为密码是已知的,工具不需要在每次编译的时候提示你输入密锁和密钥。
  • 当你的应用程序已经准备release了,你可以在release 模式下编译。release模式下,工具编译时不会将.apk文件签名。你需要用Keytool生成密钥和密锁,再用JDK中的Jarsigner工具给.apk文件签名。

 

签名基本设置

为了支持生成密锁和密钥,你首先要确定Keytool在SDK编译工具中是有效的。在很多情况下,你可以设置JAVA_HOME环境变量,告诉SDK如何找到Keytool,或者你可以在PATH变量中添加Keytool的JDK版本。

如果你是在linux版本中开发,原本是来自Java Gnu编译器,请确定系统用的是Keytool版本的JDK,而不是gcj版本的。如果Keytool已经在PATH中,它将指向符号连接/usr/bin/keytool。这种情况下,核实符号连接的目标是指向JDK下的Keytool

Eclipse/ADT中的签名

如果你是在Eclipse下开发,并已经按照上面所介绍的安装了Keytool,默认情况下是可以在debug模式下签名的。当你运行调试程序的时候ADK将给.apk文件签名,并安装到模拟器上。这部分不需要特殊的动作,ADT已经进入Keytool

在release模式下编译程序,在Package面版上按project右键,选择Android Tools>Export Application Package.或者你可以点击Manifest Editor, overview 页面上的“Exporting the unsigned .apk”连接 ,导出未签名apk文件。保存.apk文件之后,用Jarsigner及你自己的密钥给apk文件签名 ,如果没有密钥, 你可以用Keystore创建密钥和密锁。如果已经有一个密钥了,如公共密钥,就可以给.apk文件签名了。

Ant签名

如果用Ant编译.apk文件,假设你使用最新版的SDK中包含的activitycreator工具生成build.xml文件,默认情况下可以使用debug签名模式。当你运行Ant对build.xml编译程序,build脚本将生成密锁和密钥并签名.apk文件。这部分不需要做其它特殊的动作。

release模式下编译程序,你需要做的是在Ant命令中指定编译目标“release”。例如,如果是在bulid.xml所在目录下运行ant,输入以下命令:

ant release

build脚本编译程序时并没有签名。编译完.apk文件后,你需要用Jarsigner和你自己的密钥给.apk文件签名。如果没有密钥, 你可以用Keystore创建密钥和密锁。如果已经有一个密钥了,如公共密钥,你就可以给.apk文件签名了。

调试证书期限

自签名证书用于程序的debug模式下(默认情况下是Eclipse/ADT 和Ant builds),自它创建时间起有一年的期限。

当证书到期时,将会有编译错误。 And下错误显示如下:

debug:
[echo] Packaging bin/samples-debug.apk, and signing it with a debug key...
[exec] Debug Certificate expired on 8/4/08 3:43 PM

在Eclipse/ADT下,你可以看到类似的错误。

解决这个问题的简单方法是删除debug.keystore文件。Linux/Mac OSX下这个文件保存在~/.android下,windows XP下,文件保存在 C:\Documents and Settings\<user>\Local Settings\Application Data\Android。windows Vista下文件保存在 C:\Users\<user>\AppData\Local\Android

下次编译时,编译工具将生成新的密锁和密钥。

注意:如果你的开发设备使用的是non-Gregorian locale,编译工具经常错误的生成一个过期的调试证书,因此编译的时候你会得到错误提示。 对于解决信息,请参见疑难解答专题 I can’t compile my app because the build tools generated an expired debug certificate.

 

使用ApiDemo示例应用程序

Android SDK包含了一套示例程序,他们验证了许多功能以及API的用法。ApiDemos软件包被提前安装在模拟器中,所以你可以启动模拟器,在主画面的应用程序抽屉里打开它。

你也可以在<SDK>/samples/ApiDemos中找到源码,可用看看它,学习Demo的实现方法。

如果你愿意,你还可以将ApiDemo的示例程序作为一个工程加载进来,修改并在模拟器上运行。然而,在这之前你首先要卸载之前已经安装的ApiDemos。如果你没有移除之前安装的版本而直接在开发环境中运行或修改ApiDemos,将会有安装错误。

关于如何卸载和重装ApiDemo,可以参考I can’t install ApiDemos apps in my IDE because of a signing error.这样你就可以在你的开发环境中工作了。

调试

Android有相当广泛的一套工具帮助你调试你的应用程序:

  • DDMS -一个生动的程序,它支持端口转换(因此你可以在IDE中给你的代码下端点),支持抓取模拟器屏幕,线程和堆栈信息,以及许多其他功能。你还可以运行logcat重新获得Log信息。点击此连接查看更多信息。
  • logcat- 转储系统信息,这些信息包括,模拟器抛出错误时堆栈的运行过程以及日志信息。运行logcat,点击此连接。
    ...
    I/MemoryDealer( 763): MemoryDealer (this=0x54bda0): Creating 2621440 bytes heap at 0x438db000
    I/Logger( 1858): getView() requesting item number 0
    I/Logger( 1858): getView() requesting item number 1
    I/Logger( 1858): getView() requesting item number 2
    D/ActivityManager( 763): Stopping: HistoryRecord{409dbb20 com.android.home.AllApps}
    ...
  • Android Log - 输出模拟器上log文件信息日志类。如果你在DDMS上运行了logcat,你可以实时阅读这些信息。在你的代码中添加logging方法的调用。使用log类,你可以根据你想获得信息的重要程度不同调用Log.v(verbose),Log.d()(debug),Log.i()(information),Log.w()(warning)或者Log.e(error).来分派log信息Log.i("MyActivity", "MyClass.getView() — Requesting item number " + position)你可以用logcat阅读这些信息。
  • Traceview - Android可以将函数的调用情况以及调用时间保存到一个log文件中,你可以用图形阅读器Traceview查看详细内容。更多信息查看这个连接下的主题
  • Eclipse plugin -Eclipse插件整合了相当数量的工具(ADB,DDMS,logcat output, 以及其它功能),点击此连接查看更多信息。
  • Debug and Test Device Settings -Android揭示了很多有用的设定,例如CPU使用率和 帧速率,参看下面的 Debug and Test Settings on the Emulator

Also, see the Troubleshooting section of the doc to figure out why your application isn’t appearing on the emulator, or why it’s not starting.

此外,参看疑难解答这一节文档,以找出您的应用程序为什么没有出现在模拟器上,或为什么不开始。

 

设备上的调试和测试设置

Android允许你设置多个设定以便你测试和调试程序。获得模拟器的开发设置,可以选择Dev Tools>Development Settings。 按照以下选项将打开开发设置页(或其中之一):

  • Debug app  选择要被调试的程序,你不需要设置这个来关联调试器,但是这个变量有两个作用:
    • 防止Android在调试的断点处长时间停留时抛出错误。
    • 允许你选择Wait for Debugger选项来暂停程序启动,直到调试器被关联上(如下介绍)
  • Wait for debugger    阻塞程序加载直到关联上调试器。这样你可以在onCreate()中设置端点,这在调试Activity的启动进程时很重要。当你改变这个选项,任何当前运行的程序实例将被杀死。为选中此框,你必须如上面介绍的选择一个调试程序。这和在代码中添加waitForDebugger()是一样的。
  • Immediately destroy activities   告诉系统只要activity停止了就销毁它。 (犹如 Android必须回收内存). 这个在测试 onSaveInstanceState(Bundle) /onCreate(android.os.Bundle)代码路径 时非常有用, 否则将难以生效.选择这个选项可能带来很多问题,因为他们没有保存程序的状态。
  • Show screen updates  选中这个选项时,屏幕上任何被重绘的矩形区域会闪现粉红色。这对于发现屏幕不必要的绘图很有用。
  • Show CPU usage   在屏幕顶端显示一个CPU进度,显示CPU的使用情况。 上面红色栏显示总的CPU使用率,下方绿色栏显示目前画面的CPU使用时间。注意:一旦打开次功能就不能关掉,除非重新启动模拟器。???
  • Show background   没有activity屏幕显示时显示背景面板,这个通常在调试的时候才会发生。

模拟器重起后这些设置仍被记忆。

顶端调试技巧

快速堆栈转储
从模拟器上获得堆转储,你可以登录adb shell,用”ps”命令找到你想要的进程,然后用”kill-3″,堆栈使用轨迹将显示在log文件中。
在模拟器屏幕上显示有用信息
设备可以显示一些有用信息,例如CPU使用率,以及高亮显示重绘区域。可以在开发设定窗口打开和关闭这些功能。Setting debug and test configurations on the emulator.中有详细介绍。
你可以通过Dalvik Debug Monitor Service工具获得转储状态信息。请参考adb中介绍的dumpsys and dumpstate
获得模拟器中应用程序状态信息(dumpsys)
你可以通过Dalvik Debug Monitor Service工具获得dumpsys信息。参考adb中介绍的dumpsys and dumpstate 。
获得无线连接信息
你可以通过Dalvik Debug Monitor Service工具获得无线连接信息。在Device菜单中选择”Dump radio state”
记录跟踪数据
你可以在activity中通过调用android.os.Debug.startMethodTracing()来记录函数的调用以及其它跟踪数据。详细的参考Running the Traceview Debugging Program
记录无线数据
 
默认情况下系统不记录无线数据(数据很多)。然而,你可以用下面的命令记录无线数据: 

adb shell
logcat -b radio

运行adb

Android 有adb工具,他提供了许多功能,包括移动和同步文件到模拟器上,改变端口,在模拟器上运行 UNIX shell。 详见Using adb
获得模拟器屏幕截图
Dalvik Debug Monitor Server (DDMS)可以抓取模拟器屏幕截图。
 
使用调试帮助类
Android为方便使用提供了调试帮助类,例如util.Log 和 Debug

编译安装Anroid应用程序

Android要求专门的编译工具可以正确的编译资源文件和应用程序的其他部分,因此,你必须为你的应用程序建立一个专门的编译环境。

专门Android编译器编译步骤包括,编译XML和其他资源文件并创建合适的输出格式。编译好的Android应用程序是一个.apk压缩文件,它含有.dex文件,资源文件,原data文件,以及其他文件。你可以通过scratch,或者源文件构造一个合适的Android工程。

Android目前不支持的在本地代码上开发第三方应用程序。

比较推荐的Andriod应用程序开发方法是use Eclipse with the Android plugin,它支持编译,运行,调试Android应用程序。

如果你还有其他IDE,Android provides tools for other IDEs 可以编译运行Android应用程序,但是他们不是很完整。

移出一个Android应用程序

移出一个安装在模拟器上的应用程序,你需要执行adbrun adb删除.apk文件。.apk文件是在安装的时候发送到模拟器上的。使用adb shell进入设备的shell,切换到data/app目录下,用rm命令删除apk文件 :rm your_app.apk。用法在连接中介绍。

Eclipse技巧

在Eclipse上执行任意java代码

在Eclipse上,当程序停在断点处时你可以执行任意代码。例如,在一个含有“zip”字符串参数的函数中,你可以获得软件包信息,调用类方法。你也可以执行任意静态方法:如,输入 android.os.Debug.startMethodTracing() ,启动 dmTrace。

打开代码执行窗口,主菜单中选择Window>Show View>Display,打开显示窗口,一个简单的文本编辑器。输入你的代码,高亮显示文字,单击’J'图标(或者CTRL + SHIFT + D)运行代码。代码在被选线程的上下文中运行, 而这个线程必须是停在断点处或者单步停止点。(如果你手动挂去线程,你必须单步执行。线程停在Object.wait()是没有用的)。

如果你目前是停在断点,你可以简单的按下(CTRL + SHIFT + D)高亮并执行一段代码。

你可以高亮同一选中区域的文字,通过按下 ALT +SHIFT + 向上/向下箭头来改变所选区域的大小

下面是一些例子,输入内容和eclipse 显示窗口的回应信息。

Input Response
zip (java.lang.String) /work/device/out/linux-x86-debug/android/app/android_sdk.zip
zip.endsWith(".zip") (boolean) true
zip.endsWith(".jar") (boolean) false

你也可以利用剪贴板在不调试时插入执行代码。在eclipse文档中查找”scrapbook”相关。

手动运行DDMS

虽然推荐用ADT插件调试程序,但是你也可以手动运行DDMS,配置Eclipse以便在8700端口上调试程序(注意:首先确定你启动了DDMS)。

增加JUnit测试类

在Eclipse/ADT ,你可以在程序中添加JUnit测试类,然而,测试运行正常之前你需要设置专门的JUnit 配置,

关于如何设置JUnit配置的详细细节,参看请参见疑难解答专题I can’t run a Junit test class in Eclipse

Bookmark and Share

安装 SDK

This item was filled under [ 一步一步学习 ]

本页内容介绍如何安装Android SDK和设置你的开发环境。如果你还没有下载SDK,你可以点下面的连接进行开始下载,然后阅读后续文档学习如何安装,并使用此SDK来创建Android应用程序。

系统和软件需求

用Android sdk的代码和工具开发Android应用程序,你需要下面列出来的合适开发电脑和开发环境.

所需操作系统:

  • Windows XP 或 Vista
  • Mac OS X 10.4.8 或更高版本 (仅支持x86)
  • Linux ( Linux Ubuntu Dapper Drake 版本已测试)

所需开发环境:

注: 如果你的电脑上已经安装了jdk,请确定它是上面所列的版本号。另外需要注意有些linux版本可能包含有jdk 1.4 或者 java 的gnu编译器,Adroid开发是不支持在这两种版本

安装 SDK

下载完SDK后,把.zip文件解压到你电脑上合适位置 默认情况下, SDK文件被解压到 android_sdk_<platform>_<release>_<build>文件夹. 这个文件夹包含tools/samples/等.

请注意系统里SDK解压后的文件夹的名字和位置 — 当你安装Android插件和使用SDK工具时,你将需要引用这个文件夹

你可以添加 SDK tools 的文件夹路径为你的路径. 如上所述, tools/文件夹位于SDK文件夹.

  • Linux环境下,修改~/.bash_profile或者 ~/.bashrc文件. 寻找路径环境变量设置的那一行添 tools/为路径环境变量.如果你没有找到这一行,你需要添加一行:
      export PATH=${PATH}:<your_sdk_dir>/tools
  • Mac环境下,在你的home文件夹里面查找.bash_profile,然后和linux一样处理。如果以前没有.bash_profile文件夹可以创建它。
  • Windows环境下, 右击我的电脑( My Computer), 并选择属性(Properties). 在标签页高级(Advanced), 点击环境变量( Environment Variables),当对话出现, 在系统变量(System Variables) 栏目里双击路径 ( Path ) .并添加tools/ 文件夹的完整路径.

添加 tools 到你的路径使你运行Android Debug Bridge (adb)和其他命令行tools ,不需要为工具路径添加完整路径.需要说明的是,如果你升级你的SDK路径不同 ,你需要记得更新你的路径 (PATH )到新的位置.

安装 Eclipse 插件 (ADT)

如果你要使用 Eclipse IDE作为开发Android应用的环境,你可以安装支持Android工程和工具的通用插件Android Development Tools (ADT). ADT插件包含强大的扩张,使得创建,运行和调试Android 更快速,更简单。

如果你不使用 Eclipse IDE,就不必下载和安装ADT插件

下载和安装ADT插件,请按照你们各自Eclipse版本步骤安装。

Eclipse 3.3 (Europa) Eclipse 3.4 (Ganymede)
  1. 开始Eclipse,然后选择 Help > Software Updates > Find and Install….
  2. 对话框出现后,选择 Search for new features to install 点击 Next.
  3. 点击New Remote Site.
  4. 在结果对话框,输入远端站点的名字(如Android Plugin),输入站点如下:
    https://dl-ssl.google.com/android/eclipse/

    点击OK.

  5. 你可以看到添加到搜索列表(并检查),可以看到新的,点击Finish.
  6. 在下面的搜索结果对话框,选择复选框 Android Plugin > Developer Tools. 它将会检查特性: “Android Developer Tools”, 和 “Android Editors”. Android 编辑器的特性是可选的,如果你选择安装它,你需要前面提到的WST插件.点击 Next.
  7. 阅读许可协议,然后选择接受许可协议 Accept terms of the license agreement,点击 Next.
  8. 点击 Finish.
  9. ADT插件没有签名,你可以接收点击安装所有来安装,
  10. 重启 Eclipse.
  1. 启动 Eclipse, 选择 Help > Software Updates….
  2. 在出现的对话框里,点击标签页 Available Software.
  3. 点击 Add Site…
  4. 如下面地址一样输入:
    https://dl-ssl.google.com/android/eclipse/

    点击 OK.

  5. 返回可用软件的视图,你会看到这个插件. 选择下一步到 Developer Tools 并点击 Install…
  6. 在接下来的安装窗口,选中”Android Developer Tools”和 “Android Editors”.Android编辑器特性是可选的,但是推荐安装.,如果你选择安装它,你需要,安装本页前面提到的WST插件。
    点击 Finish.
  7. 重启 Eclipse.

重启之后, update your Eclipse preferences 指向SDK文件夹:

  1. 选择 Window > Preferences… 来打开属性面板. (Mac OS X: Eclipse > Preferences)
  2. 从左边面板选择 Android。
  3. 在主界面上定位SDK 点击 Browse… 然后定位 SDK文件夹.
  4. 点击 Apply, 然后点击 OK.

ADT 安装疑难解答

I你如果按照以上步骤下载ADT插件有疑问,下面给您一下建议:

  • 在第四步,尝试改变远程更行地址URL为http,而非 https.
  • 如果你在防火墙后面(公司防火墙)请确定你的Eclipse的代理设置合适。在Eclipse 3.3/3.4,你可以从主Eclipse按钮中 Window (在 Mac, Eclipse) >Preferences > General > Network Connections来配置代理.

如果无法安装下载的ADT插件到Eclipse,按照如下的步骤来从你的电脑下载和安装插件:

  1. 下载ADT压缩文件 (不解压).
  2. 按照默认安装的第一部和第二步(如上).
  3. 在 Eclipse 3.3, 点击New Archive Site…
    In Eclipse 3.4, click Add Site…, 然后点击Archive…
  4. 浏览和选择已经下载的压缩文件。
  5. 从第五步开始完成上面剩下的流程。

更新你的插件,你必须按照这些步骤代替默认的更行说明。

Note that the “Android Editors” feature of ADT requires several optional Eclipse components (for example, WST). If you encounter an error when installing ADT, your Eclipse installion might not include those components. For information about how to quickly add the necessary components to your Eclipse installation, see the troubleshooting topic ADT Installation Error: “requires plug-in org.eclipse.wst.sse.ui”.

更新 ADT 插件

在某些情况下,一个你当前的SDK可能变得适合你的新的ADT插件,你可以用以下步骤从Eclipse里更新ADT插件。

Eclipse 3.3 (Europa) Eclipse 3.4 (Ganymede)
  1. 选择 Help > Software Updates > Find and Install….
  2. 选择Search for updates of the currently installed features 并点击Finish.
  3. 如果 ADT允许更新,选择并安装更新。

或:

  1. 选择 Help > Software Updates > Manage Configuration.
  2. 展开导航树并选择 Android Development Tools <version>
  3. Available Tasks 下选择 Scan for Updates
  1. 选择 Help > Software Updates…
  2. 选择标签页 Installed Software
  3. 点击 Update…
  4. 如果 ADT允许更新,选择它并点击 Finish.

安装注意事项

Ubuntu Linux 注意事项

  • 如果你需要帮助安装和配置java在你的开发机上,你可以发现以下资源帮助:
  • 这里有java和Eclipsed的步骤,优先安装Android SDK和ADT 插件.
    1. 如果你你开发机上使用64位版本,你需要用 apt-get安装 ia32-libs 包
      apt-get install ia32-libs
    2. 下一步,安装 Java:
      apt-get install sun-java6-bin
    3. Ubuntu 包管理器现在没有提供Eclipse 3.3版本下载,因此我们推荐你从eclipse.org (http://www.eclipse.org/ downloads/). 建议使用Java或RCP版本的Eclipse.
    4. 按照前面部分的提供步骤来安装SDK和ADT插件.

其他版本 Linux 注意事项

  • 如果你在安装Eclipse的ADT插件遇到这个错误:
    An error occurred during provisioning.
    Cannot connect to keystore.
    JKS

    如果你的开发环境缺少合适的虚拟机,安装 Sun Java 6可以解决这个问题,然后你再重新安装ADT插件。

  • 如果JDK已经安装到你的开发电脑上,请确定在这页的顶部列出的所选择的版本,有些Linux包含jdk1.4或者java的gnu编译器,以上二者Android开发不支持。
Bookmark and Share
Page 2 of 2«12