2008年11月26日星期三

转:从《西游记》和《魔戒》看东西方项目管理

打开电视,电视里正在播放《魔戒第一部.护戒使者》。面对墨多的黑君主索伦无以伦比的可怕力量,一个义无反顾的护戒小队成立了,他们的目标就是墨多的核心地带——末日火山。这看起来就像是一个不可能完成的任务,一开始就面临着难以逾越的劫难。这让我想起了我们的神怪小说《西游记》,同样是一个团队,同样是面临千难万险的征途,但是,中西方文化的差别却在这里表现得淋漓尽致。

首先,我们看看这两个团队的成立

“你挑着担,我牵着马,迎来旭日送走晚霞。。。。”这首歌好像描绘了一个非常和谐的,分工明确、责任清晰的最佳合作团队。但是,这个团队起初只有唐僧一个人,只有唐僧才真正明白此行的目的,一行四人中最坚决的取经者仅此一人而已。其他几位包括白龙马、孙悟空、猪八戒、沙和尚等基本上都是连哄带骗外加紧箍咒强行拉壮丁拉进来的,这几个人各打各的主义,各有各的心思,可以这样说:他们怀着不同的目的,为了同一个目标,走到了一起。

而护戒使者小分队的成立,则完全是另外一个样子。首先在精灵国的林谷会议上,大家对面临的问题非常清晰,索伦要找回魔戒,得到魔戒的索伦将成为不可战胜的力量。那样的话,人类、精灵、矮人、侏儒等一切爱好和平的种族将会面临灭顶之灾,解决问题的唯一办法就是将魔戒带到墨多的核心末日火山,然后将魔戒丢到火山中将其毁灭。但是,达到这个目的的困难是完全不可想象的,其难度完全不亚于去西天取经。这时候,英勇无畏的勇士们站了出来。游侠阿拉贡、战士博罗米尔、精灵莱格拉斯、矮人金利、巫师甘道夫以及几个以弗罗多为首的霍比特人,九个人的护戒使者可以说目的非常明确(皮平除外),而且完全是自发的主动的建立起这个团队。这个团队没有明确的队长,只有带戒人和护戒使者,遇到事情基本上采取协商解决。

从团队建设来看,东方文化带有明显的阶级因素。最高阶级是神,如来佛、观音菩萨、玉皇大帝等,神是法力无边的,与神斗,绝没有好下场,齐天大圣够厉害了吧?最后还不是逃不出如来佛的手心,如来佛一翻手掌就将他压在五界山下永世不得脱身。第二个阶级是师傅唐僧,唐僧作为神的代言人,具有管辖和掌握手下四个徒弟的特权,他忠实地行使神赋予他的权力和义务。但是神给他的权力是明确的,有限的,他只能管理这几个徒儿,除此之外,即便是面对狐狸兔子等最下等的小妖,他也无能为力。再下面是三个人形的徒弟,尽管他们个个长的实在没个人样,但是与连人形也没有修得的白龙马相比,他们显然要高一个阶级。在这个第三阶级里面,每个人的地位也是不平等的,因为唐僧给他们排了座次,大师兄悟空,二师兄八戒,三师弟沙僧,人人都有自己的位置安排,遇到事情大家依据自己的位置发表议论。如果谁违背了这个顺序,后果将不堪设想。唐僧曾经听信了八戒的谗言,忽视了大师兄悟空的权利,孙悟空越想越气,最后一怒之下撂挑子不干了。可见,在西游团队中,需要论资排辈,每个人既定的地位、座次都是非常重要、不可动摇地。最后一个阶级就是大家的奴隶——白龙马。白龙马说起来也是龙的传人,可惜他被神定位为马,从此只能负重行走,没有说话的权利,连吃饭也没份,是一个活脱脱的奴隶。

而西方文化,更看重个人的尊严。在护戒使者这个团队中,每个人都有他存在的价值,他们的地位是平等的。开始时,山姆是弗罗多的仆人,但是弗罗多以及其他小组成员从没有把他当奴隶看,最后,随着大家一起克服重重困难,弗罗多完全把山姆当成了自己的亲兄弟。因为没有不可逾越的阶级,人与神的界限就没有那么明显,黑君主索伦是强悍无比的黑暗势力,但是,只要你有足够的勇气,即便你是一个普通人,一样有可能打败他。

其次,我们来看一看两个团队如何处理所面对的困难

西游团队碰到困难时,师傅是不出面的。就像大话西游里唱得那样:“背黑锅我来,送死你去!”唐僧作为领导,当然是养尊处优的,碰到难处理的事情,你们三个去想办法。这时候,这三个人的责任便很明确,大师兄地位高,自然承担的责任也最大,降妖除怪一般都是大师兄责无旁贷。孙悟空也从来不推托,总是第一个冲了上去,这时候东方文化的良好秩序发挥了效率。由于地位清晰,责任明确,大家该干什么干什么,碰到妖怪,唐僧只要说一句:“悟空,你去看看!”接下来降妖机器便自动运转起来,来一个妖怪是这个打法,来一百个妖怪,也是这个打法。每个人对自己的工作都驾轻就熟,孙悟空自然是打妖的主力,八戒主要保护师傅,有时候是机动力量,由于能力有限,常常充当第二梯队打打二流小妖;沙僧地位最低,责任也最小,只要看好行李物品不要丢失就行了。白龙马是奴隶,没有地位,自然也没有责任,打不打妖和他没有任何关系,谁也不会把责任推到他的头上。

而护戒使者队伍因为大家地位相同,因此碰到怪物的时候,只要喊一声:“大家并肩子上啊!”便人不分老幼,地不分南北一拥而上,打得个不亦乐乎。虽然大家的能力是不一样的,但是杀敌的勇气却是一样的,面对蜂拥而至的妖怪,谁也不能够独善其身,只能拿起武器战斗。这种同进同退的战斗生活,能够加深团队成员之间的友谊,实际上这个团队最终大家都成了生死兄弟。一个兄弟般的团队,其战斗力自然会更强,正所谓:“兄弟同心,其利断金!”正是这个互相关心,共同努力的团队,面对一次次令人绝望的危险,都能够涉险过关。

这两种不同的态度,所造成的后果也是各有千秋。东方人讲秩序,讲责、权、利分工明确,“各人自扫门前雪,莫管他人瓦上霜”这句话便是东方人处世态度的最好写照。作为团队的管理者,最核心的问题就是赏罚分明,只有纪律严明赏罚分明的队伍才是一个有能力的团队。而西方人鼓动人的主动性、积极发挥个人的创造力,要求团队更主动,更合作,团队管理的核心是激发每个人的主观能动性与创造力。


第三,我们再看看两个团队处理问题的方式

西游团队碰到危险,总是按照一定的思维方式来处理。首先,孙悟空会看到一股妖气,或者孙悟空的火眼金睛看出对方是妖怪,然后孙悟空先上去斗法。如果斗法成功,则为民除害,大家继续上路。如果斗法不成功,十有八九唐僧师徒被捉,这时候悟空总是有法子脱身,然后便会去找更厉害的帮手。通常帮手都是是天上位列仙班的大罗神仙,或者观世音菩萨的同道中人。而那些妖怪十有八九都是这些人的家眷、门人或者家禽家畜等等,因为有了这一层关系,便下界为祸人间。对待这些妖怪,孙悟空是搞不定的,因为他们出身高贵,必须找到 他们的上级才能够把问题解决。

西游记的九九八十一难,十有八九是因为高层领导的裙带关系,家属腐败等等原因造成的。所以,尽管取经路上危险重重,但是大家心里并不担心,为什么?因为一切尽在掌握中。所有的磨难或者危险,都是有因有果,都逃不出这四大阶级的天罗地网。只要这个阶级秩序能 够保持稳定,一切困难都会迎刃而解。

因此,西游团队面对问题的时候,他们首先回来分辨这个妖怪到底是什么来历?也就是说,妖怪的出身很重要,知道了妖怪的出身,问题也就解决了一大半了,接下来无非是怎样起出妖怪背后的最大靠山而已。这也符合东方文化的谋定而后动的操作要领,最后收拾妖怪,不过是整个行为的收关之作,整个降妖过程,很多工作都在幕后进行。所谓“功夫在诗外”,诗写道好的关键是你能够有足够的素材。通过自己的人情脉络找出那个真正的谋后主使,才是孙悟空能够降妖除魔的看家本领。

护戒使者所碰到的磨难,往往是突发的,没有任何征兆的,也绝不可能通过外援来调解的。他们没有一个掌控全局的神来主持大局,有的只是正义和邪恶两个完全不可调和的对立面,要么杀死敌人,要么被敌人杀死。水怪、炎魔、布鲁克武士、狼骑士,所有的敌人都是呼啸而来。应付的办法也是出奇的简单,拿起武器拼个你死我活。西方文化当中的正义与邪恶观点相对来说要幼稚的多,与西游团队不同,护戒使者面对敌人时,采取最直接也最有效的解决办法。在这种情况下,一切的运筹帷幄、一切的人情世故都是没用的,取胜只能靠自己的 力量、勇气、信心和敏捷的反应能力。

在应急处理问题的方式上,东西方文化截然不同的反应,给我们很大的启示。面对困难,西方人总是鼓励你主动地、勇敢地去尝试,或许你的方法完全不对,但是只要你有勇气尝试去解决问题,你就会得到尊重。西方文化更看重你解决问题的态度。与此相反,东方人在面临巨大困难的时候,他们首先考虑的是如何解决,或者如何选择最恰当的方式来解决问题。而不是贸然动手,如果你贸然动手,一旦你失败了,可能会招致大量的批评。

这种解决问题的思维方式,已经深深的烙在每一个人的心里。我们在教育方面,会花费大量的精力来告诉学生事物的原理,我们有十万个为什么?我们有格物致知的祖训,我们每个人都在探索事情的规律和论证最佳的解决方案。我们唯独忘了鼓励小朋友大胆去尝试自己的想法;我们总是告诉小朋友正确的解决方法,但是却忘了告诉小朋友如何通过自己的尝试获得正确地解决方案。授人以鱼不如授人以渔,很多人已经发现了我们教育方面的问题,但是扭转局面谈何容易,因为我们的文化根源与西方文化是那么的格格不入。我们的高考制度,考的是你能否给出问题的正确答案,而不是你能否以正确的方式来回答问题。高考制度不改变,模仿西方的所谓素质教育将永远是一句空话。

扯远了,我想如果西游一行碰到得九九八十一难都是像护戒使者面对的那样的敌人的话,唐僧可能已经死了七八十回了。但是,你放心,东方的妖怪也是东方化的。当他们捉住了唐僧,通常都不会便吃,而是要弄清楚齐天大圣走了没有?危险过去了没有?有的妖怪更是可爱的很,他们会很有孝心的邀请自己的长辈来共食,这样的妖怪自然给悟空留下了足够做好后台工作的时间,足以让你找到解决问题的法门。东方的妖怪还是比较仁义的,抓住唐僧后会对悟空说:不是我没给你机会阿,你要抓紧时间来救你师傅啊,你不来救可就莫怪我嘴下不 留情了。

第四,两个故事的结局

西游的结局大家都知道,五个人取经成功修的正果,都脱离苦海成了佛。而护戒使者一行人,除了为此事业献身的波罗米尔,其他人奋斗的结果便是成功阻止了索伦的强大,其结局非常简单。

从两个故事的结局可以清楚地看到,东方人功利思想要重得多,尽管当初一行人各怀鬼胎走上去西天取经之路。但是,当取经成功之后,孙悟空也老是不客气地做起了佛爷,那花果山的猴头看样子到底没有做佛爷来的风光啊。

但是在西方人眼里,成功就是任务的完成,对成功者来说,这件事情本身就够他自豪一辈子了,其他虚名则可有可无。

近年来,西方拍了很多的灾难片,有火山爆发的,有龙卷风的,有地震海啸的,有暴风雪的。在这些片子里,主人公无一例外的尝试去对抗大自然的力量。人类还没有取得应付自然灾害的能力,这时候面对它和解决它的勇气非常重要。东西方文化各有所长,但是,在我们这一代以及我们的下一代,在面对突发事件的情况下,我们的应变能力显然已经落于人后。

从西游记与魔戒这两部神怪小说分析,东西方文化有他根源上的巨大差异。东方文化胜在秩序的稳定和对事物原理孜孜不倦的追求上。而西方文化在人性的尊重,个性化创造力的培养,以及鼓励主动尝试等方面略高一筹。二十一世纪是全球一体化时代,东西方文化的融合将成为大家关心的主题。为了我们的下一代,西方一些优秀的教育理念是值得我们研究和学习的。

Hello, Android!

Hello, Android!

作为一个开发人员,你得到一个开发框架的第一映像是编写“Hello, World!”程序是否容易,对于Android,他是非常容易的。

创建项目

创建项目能有多容易就多容易。获得Eclipse插件使Android开发非常容易。
你需要安装有EclipseIDE的开发计算机,你还需要安装ADT插件。一旦你准备好了,你现在就可以开始进入开发。
首先,下面是高度概括的建立"Hello, World!"程序的方法:
1)在菜单File > New > Project中创建一个新的"Android Project"
2)在New Android Project对话框中填写项目详细信息
3)编辑自动产生的源代码模板以便使程序显示一些输出信息
这就是全部!下一步,让我们详细进入每一步。

1、创建一个新的Android项目
从Eclipse中,选择菜单File > New > Project。如果ADT插件成功安装,结果对话框应该有一个标记为“Android”的文件夹,该文件夹包含一个简单入口:"Android Project"。
一旦你选择了"Android Project"文件夹,点击Next按钮。
2、填写项目详细信息
下一步的屏幕允许你填写项目详细信息。下面是例子:


以下列出这个屏幕的每个字段的意思:
(1)Project Name
这是存放该项目的目录或者文件夹名称。
(2)Package Name
这是包的名称空间(JAVA语言针对包使用同样的规则),你的所有代码均驻留在该命名空间中。同时也设置了即将产生的桩活动下面的包名称
你用在应用程序中的包名称必须在系统安装的所有包中唯一;基于这样的原因,你的应用程序使用标准域风格的包是非常必要的。上面的例子中,你使用了包域“com.android”;你应该使用一个不同的名字,根据你的组织做适当变化。
(3)Activity Name
这是类桩的名称,类桩(class stub)由插件产生。这是Android活动的子类。一个活动是一个能运行和完成一定工作的简单类。如果选择的话,能创建一个UI,但是不是必要的。
(4)Application Name
这是你的应用程序供使用者查看的标题。

复选项切换选项“Use default location”允许你改变磁盘位置,该位置用于项目文件产生和保存。

3、编辑自动产生的源代码

插件运行后,你将会有一个称为HelloAndroid的类,位于包HelloAndroid > src > com.android.hello。它看起来是这样的:
public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
@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 {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
tv.setText("Hello, Android");
setContentView(tv);
}
}

提示:如果你忘记引入TextView包,请试着做:按Ctrl-Shift-O (Cmd-Shift-O, 在 Mac操作系统上),这是一个Eclipse组织引入操作的快捷键——他自动识别丢失的包并为你自动加入。

Android的UI由叫做Views类的体系构成。一个View是一个简化的绘图对象,比如单选按钮、动画、文本标签。处理文本的View子类的名称为TextView。
下面是你建立TextView的方法:
TextView tv = new TextView(this);

TextView的构造函数的入参是Android Context实例。Context是系统的句柄;它提供诸如资源解析、数据库访问、参数选取等服务。Activity类继承自Context。因此,我们的HelloAndroid类是Activity的子类,它也是一个Context,所以我们能把this引用传送给TextView。
一旦我们建立了TextView,我们需要告之显示什么:
tv.setText("Hello, Android");

这里没有什么太令人惊讶的。
在此处,我们建立了TextView,并告之显示什么文本内容。最后一步是连接这个TextView到屏幕显示,像这样:
setContentView(tv);

在Activity中的setContentView方法指示系统和Activity的UI联系起来。如果一个Activity没有调用这个方法,根本没有UI出现,系统将会显示一个空白屏幕。为了我们的目的,我们想的所有事情是现实一些文本,因此我们传送文本给才创建的TextView。
这就是Android的“Hello, World”!下一步我们来看看他怎样运行的。


运行代码:Hello, Android

ADT插件非常容易运行应用程序。选择菜单Run > Open Run Dialog开始,Eclipse3.4,选择菜单Run > Run Configurations。

下一步,选中"Android Application"条目,然后点击左上角的图标(在角上画有加号的一张纸),或者双击"Android Application" 入口。这样,你就有了一个叫“New_configuration”的新的入口条目。

修改名称来表达要做的事情,比如"Hello, Android",然后双击Browse按钮来选取你的项目。(如果你在Eclipse中打开了不止一个项目,保证你选取正确的一个。)
插件自动扫描你的项目以寻找活动子类,自动添加找到的每一个到"Activity:" 标签下的下拉列表中。因为,你的 "Hello, Android"仅仅有一个,所以它将会是默认的一个活动子类,你可以继续下面的步骤。
点击“Apply”按钮。

那就是他,大功告成!点击Run按钮,Android模拟器应该会启动。一旦模拟器启动,你的应用程序将会显示出来。当说过和做过这一切,你应该会看到这样的事情:
在Android中显示“Hello, World”。非常简单。教程的下一章提供更多的详细信息,你可以找到你能更多了解Android的有价值的内容。

2008年11月24日星期一

设备调式和测试设置

设备调式和测试设置

Android让你设置需许多设置,这些设置会让测试和调试应用程序更容易。进入模拟器的开发设置页的方法:进入菜单“Dev Tools”-->“Development Settings”,系统会打开开发设置页面,里面包含如下的选项:
* Debug app——选中将要调式的应用程序。你不需要设置这个来attach绑定一个编辑器,但是设置这个值两种效果:
(1)如果你调试时长时间暂停在断点上,这个设置会阻止Android抛出异常。
(2)这个设置会使你选择“Wait for Debugger”选项,该选项会暂停应用程序启动直到你的调试器重新联系上。
* Wait for debugger——阻止被选择的应用程序调用直到一个调试器被依附。你能用于在OnCreate()上设置断点,在调试一个活动的启动过程时很重要。当你变更这个选项时任何正在运行的被选择的应用程序将会被终止。为了能选中这个选项,你必须象上一个选项描述的那样选中一个调试应用程序。你能通过在代码里面调用waitForDebugger()来达到同样的目的。
* Immediately destroy activities——告诉系统一旦活动停止就摧毁这个活动(类似Android回收内存)。这有助于测试onSaveInstance(Bundle)/onCreate(android.os.Bundle)代码执行路径,否则强制测试是很困难的。选用这个选项会恰当暴露许多程序问题,这些问题多半是不节约内存。
* Show screen updates——瞬时刷新一个粉红色的矩形框,在正在重画的任何屏幕区域。这个选项非常有利于发现不必要的屏幕重画动作。
* Show CPU usage——在屏幕顶端显示CPU仪表盘,用于显示CPU使用了多少。顶上的红色条显示全部的CPU使用,下面的绿色条显示话费在组合屏幕上的CPU时间。注意:一旦打开你不能关闭这个功能,除非你重新模拟器。
* Show background——当没有活动屏幕可见时显示一个背景屏幕。一般不会发生,但是调试期间可能发生。
这些设置经过模拟器重启后被记住。

顶级调试技巧

快速堆栈转储
为了从模拟器上获得堆栈转储,你可使用adb外壳登录,使用ps命令找到你想要的进程,然后使用kill -3。堆栈跟踪会显示在日志文件中。
在模拟器屏幕显示有用的信息
设备能显示有用的信息,比如CPU使用情况或者高亮显示重画区域。在开发设置窗口中打开或者关闭这些设置,参见“Setting debug and test configurations on the emulator”
从模拟器(dumpstate)中获取系统状态信息
从Dalvik调试监视器服务工具上你能访问dumpstate(转储状态)信息。参见adb主题页的“dumpsys and dumpstate”

从模拟器(dumpsys)中获取状态信息

从Dalvik调试监视器服务工具上你能访问dumpsys(转储系统)信息。参见adb主题页的“dumpsys and dumpstate”

获取无限连接信息

从Dalvik调试监视器服务工具上你能访问无线连接信息。从Device菜单中,选择“Dump radio state”

记录跟踪数据

你能记录活动中的方法调用以及其他跟踪数据,方法是:调用android.os.Debug.startMethodTracing()。参见“Running the Traceview Debugging Program”。

记录无线电数据

默认情况下,无线电信息不记录在系统中,因为数据量很大。但是,通过下面的命令打开无线电数据记录功能。
adb shell
logcat -b radio

运行adb

Android使用一个提供众多能力的工具称为adb,包括移动和同步模拟器文件、转发端口、在模拟器上运行UNIX外壳。详情请参考“Using adb”。

从模拟器中捕获屏幕

DDMS能从模拟器中捕获屏幕截图。

使用调试帮助类

Android提供调试帮助类,比如util.Log,方便调试。


生成和安装Android程序

Android需要定制生成工具,以便能够恰当的生成资源文件和应用程序的其他部分。正因为如此,你必须有一个针对你的应用程序特定的生成环境。

定制的Android编译步骤包括编译XMl和其他资源文件、创建合适的输出格式。一个已编译的应用程序是一个.apk文件,该文件是压缩文件,包含.dex文件、资源文件、原始数据文件以及其他文件。你可以创建一个合适结构的Android项目,从零开始,或者基于已存在的源代码。
Android目前不支持在本地代码级别(C/C++)上的第三方应用程序开发。

推荐开发方式是使用Android插件的Eclipse,提供生成、运行、调试支持。

如果你有其他IDE,Android提供工具来生成、调试应用程序,但是他们没有和IDE整合。


移除一个Android程序


为了移除一个你已经安装到模拟器上的程序,你需要运行adb并删除安装时送到模拟器上的.apk文件。使用adb外壳落入设备的命令外壳,就像相关主题描述的那样,定位到data/app/,然后使用rm your_app.apk移除文件。

Eclipse技巧

在Eclipse中执行任意Java表达式
当Eclipse展厅在一个断点时你能执行任意代码。例如,进入带称为zip的字符串参数的一个函数时,键入android.os.Debug.startMethodTracing()将会启动dmTrace。
打开一个代码执行窗口,选择主菜单下的菜单Window>Show View>Display打开Display窗口,一个简单的文本编辑器。输入您的表达式,突出显示文字,然后点击' J '图标(或按Ctrl + Shift + d )来运行您的代码。这里的代码运行在被选择的线程所在的上下文环境中,被选择的线程指在断点下停止或者处于单步运行点下的线程。(如果你手工挂起线程,你不得不一次运行一步;如果线程处于Object.wait()中就不会起作用。)
If you are currently paused on a breakpoint, you can simply highlight and execute a piece of source code by pressing CTRL + SHIFT + D.
如果你目前暂停于一个断点,你可以简单突出显示一段代码然后按“CTRL + SHIFT + D”执行之。
你能突出显示一段文本,该文本位于同一段范围内,该范围通过按ALT +SHIFT + UP ARROW选择的最大封闭块,或者按DOWN ARROW选择更小块。
这里有几个在Desplay窗口中执行的例子,还提供了执行响应。
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
你也能执行任意代码,而不是用剪贴簿来调试。请搜索和“scrapbook”相关的Eclipse文档。

手工运行DDMS

尽管推荐调试方法是使用ADT插件,但是你也可以手工运行DDMS并在8700端口上配置Eclipse。注意:保证你第一次使用DDMS。

加入JUnit测试类

在Eclipse/ADT中,你能加入JUnit测试类到你的程序中。但是,在你的测试适当运行之前,你需要设置一个自定义的JUnit配置。欲知有关怎样设置Junit配置的更多信息,请参见“ I can't run a Junit test class in Eclipse”。

2008年11月21日星期五

使用ApiDemos例子程序

使用ApiDemos例子程序

AndroidSDK包含一套例子程序,用于证明API和许多功能。ApiDemos包预装到模拟器上,因此你能访问他(通过启动一个模拟器),然后平滑打开主界面的应用程序抽屉。
你能找到ApiDemos应用程序的源代码,位于 /samples/ApiDemos目录里面,仔细考察他一边了解怎么实现的。
如果你想,你能作为源代码项目调用ApiDemos例子程序并修改他,然后在模拟器中运行他。但是,为了达到目的,你需要首先反安装ApiDemos的预装版本。如果你试图在你的开发环境中运行或者修改ApiDemos,而不是首先卸载预装版本,你会获得一个安装错误。
为了获取更多关于反安装和重新安装ApiDemos的信息,请参考问题主题文章“ I can't install ApiDemos apps in my IDE because of a signing error”。

调试

Android有一套相当广泛的工具来帮助你调试程序:
* DDMS——一款图形程序,支持端口映射(以便你在IDE中设置代码断点)、模拟器上屏幕捕获、线程堆栈信息以及其他特性。你也能运行logcat检索你的日志信息。欲知更多信息请查看相关主题。
* logcat——转储系统消息的日志。这些消息包括当模拟器抛出一个异常时堆栈跟踪,以及日志信息。为了运行logcat请参阅更过信息。
*Android Lod——一个日志记录类,用于输出消息到一个模拟器的日志文件。你能通过在DDMS上运行logcat来实时阅读消息。需要加入几个方法调用到你的代码。
为了使用这个Log类,你仅仅需要调用Log.v()(详细),Log.d()(调式),Log.i()(信息),Log.w()(警告)或者Log.e(错误),根据你的设计的日志消息的重要性来区别调用。
Log.i("MyActivity", "MyClass.getView() — Requesting item number " + position)
你能使用logcat来读这些消息。
* TraceView——Android能保存大量方法调用和次数到一个日志文件中,这个日志文件你能调用Traceview在图形阅读器中浏览。欲知更多信息请查看相关信息主题。
* Eclipse插件——Eclipse的Android插件整合了诸如ADB、DDMS、Logcat输出等工具。欲知更多信息请查看相关信息主题。
* Debug和Test Device设置——Android开放了几种设置,可以获取有用的信息,比如CPU使用率、帧速率。请参见下面的“Debug and Test Settings on the Emulator”

同时,请参见文档的问题解决章节,这些章节指出了为什么程序不能显示在模拟器中,或者为什么不能启动。

2008年11月18日星期二

签名Android应用程序

签名你的应用程序

Android系统要求所有已安装的程序必须数字签名——没有适当数字签名系统不会安装或运行一个应用程序。这适用于任何地方运行的Android系统,不管是模拟器还是实际设备。基于这个原因,在你能在一个模拟器或者设备上运行或者调试应用程序前,必须为你的应用程序设置签名。

理解Android应用程序签名的要点是:
所有应用必须签名,不签名系统不会安装这个应用程序。
你可使用自签名证书来签名你的应用程序,而不需要证书管理机构。
系统仅在安装时验证签名证书的有效期。如果应用程序的签名证书在应用程序安装后有效,应用程序的功能正常使用。
你可使用标准工具——Keytool和Jarsigner——产生钥匙并签名你的应用程序的.apk文件。

当调试时,AndroidSDK工具辅助你签名你的应用程序。Eclipse的ADT插件和Ant编译工具提供两种签名模式:调试牧师和发布模式。
调试模式:编译使用Keytool工具(这个工具包含在JDK中)以创建一个keystore和带有一个明确别名和密码的key。每次编译,这个工具使用调试key来签名应用程序的.apk文件。因为密码已知,这个工具不必每次编译时提醒你keystore/key的密码。
发布模式:当你的应用程序准备发布时,你在发布签名模式编译你的应用程序。在发布模式,这个工具编译你的.apk而不签名。你必须使用Keytool产生你自己的keystore/key,然后使用Jarsigner工具(也包含在JDK中)来签名.apk文件。

签名的基本设置

为了支持keystore和调试key的产生,你应该首先保证Keytool能在你的SDK中获取。通常情况下,只要你保证你的JAVA_HOME环境变量被设置,并且指向合适的JDK,你就能告诉SDK编译工具怎么找到Keytool。还有一种办法,你可将Keytool的JDK版本加入你的PATH变量中。
如果你在提供Gnu编译器的某个Linux版本上开发,你必须指定系统使用Keytool的JDK版本,而不是GCJ版本。若Keytool已经存在于你的PATH,他可以指向/usr/bin/keytool的链接。这种情况下,检查链接目标保证指向JDK的Keytool。

在Eclipse/ADT中签名

如果你在Eclipse中开发,并且已经按照上述步骤设置Keytool,那么签名默认采用调试模式。当你运行和调试你的应用程序时,ADT签名.apk文件,并在模拟中中安装。不需要你做指定操作,因为ADT已经成功访问了Keytool。
为了在发布模式中编译你的应用程序,右击Package面板的项目,然后选择Android Tools>Export Application Package菜单,另外一种方法:你能Manifest编辑器总页面"Android Manifest Overview"里面执行"Exporting the unsigned .apk"超级链接。在你保存了输出文件.apk后,你需要在发布前携带你自己的key使用Jarsigner来签名.apk。如果你没有一个key,你可以使用Kestroe携带合适参数来创建keystore和key。如果你已经有一个Key,比如一个公司的Key,你能使用它来签名.apk文件。

在Ant中签名

如果你使用Ant生成你的.apk文件,debug签名模式默认开启,前提是你通过包含在最新SDK中的活动创建(activitycreator)工具产生的build.xml文件。当你运行Ant使用bulid.xml来编译你的应用程序,这个生成脚本产生一个keystore/key并签名.apk文件。你自己不需要做什么特定操作。
为了在发布模式下编译你的应用程序,你需要做的所有事情是使用Ant命令指定一个生成目标“release”。例如,如果你从包含build.xml文件的目录中运行Ant,Ant命令看起来是这样:
ant release
这个生成描述脚本编译应用程序为.apk,而没有签名。当编译.apk后你需要在发布前携带你自己的key使用Jarsigner来签名.apk。如果你没有一个key,你可以使用Kestroe携带合适参数来创建keystore和key。如果你已经有一个Key,比如一个公司的Key,你能使用它来签名.apk文件。


Debug认证过期

自签名认证使用DEBUG模式下签名你的医用程序,自签名认证从创建时间开始1年后过期。
当认证过期时,你将会得到一个创建错误。在Ant中编译,错误看起来这样:
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中,你在Android控制台会看到一个类似的错误。
为了纠正这个问题,简单删除debug.keystore 文件即可。在Linux/Mac OSX操作系统中,这个文件存储在 ~/.android目录中,而在win XP操作系统,这个文件保存在C:\Documents and Settings\\Local Settings\Application Data\Android目录中。在Vista,这个文件保存在C:\Users\\AppData\Local\Android目录中。
下次你生成时,生成工具将会重新产生新的keystore和调试key.
注意,如果你的开发机器正在使用非阳历地区,生成工具可能错误地产生一个已经过期的调试认证,为此,当你试图编译你的应用程序时你会得到一个错误。欲知进一步的信息,请阅读问题主题文章“I can't compile my app because the build tools generated an expired debug certificate”。

2008年11月13日星期四

创建Android运行配置

创建Android运行配置
在你在Eclipse上运行并调试Android应用程序前,你必须为之创建一个运行配置。一个运行配置指定运行项目,启动的活动,使用的模拟器选项,等等。
为了针对你的应用程序创建运行配置,根据你的Eclipse版本选择合适的步骤:
1、打开运行配置管理器
(1)3.3
选择Run > Open Run Dialog... 或者Run > Open Debug Dialog...
(2)3.4
选择Run > Run Configurations... 或者Run > Debug Configurations...
2、在左边的工程类型列表中,定位the Android Application条目,双击之或者右键> New, 以创建一个新的运行配置.
3、键入一个配置名称
4、在Android可选页, 浏览确定启动的项目和活动.
5、在Target可选页, 设置喜好的屏幕和网络特性,以及其他模拟器启动选项.
6、你也可以根据喜好在Common可选页设置额外的选项.
7、点击Apply以保存运行配置,或者选择 Run 或者 Debug 按钮.

运行和调试一个Android应用程序

一旦你为你的应用程序设置了项目和运行配置,你可以根据下面的描述运行或者调试之。
从Eclipse主菜单,根据情况选择Run > Run 或者 Run > Debug子菜单,可运行或者调试激活的运行配置。
注意:激活的运行配置是在运行配置管理器中最后选择的一项运行配置。这不一定匹配你在Eclipse导航窗体中选择的应用程序(如果有的话)。
为了设置或者修改激活的运行配置,你要使用运行配置管理器。怎样访问运行配置管理器,要知道更多信息请阅读“Creating a Launch Configuration”(创建Android运行配置)。
运行或者调试应用程序触发以下操作:
1、如果还没有模拟器在运行,则启动模拟器。
2、如果比较最后的编译文件,程序代码已经改变,则重新编译,然后在模拟器中安装应用程序。
3、使用“Run”菜单启动应用程序。
4、使用“Debug”菜单启动应用程序进入“Wait for debugger”(等待调试)模式,然后打开调试试图,针对应用程序使用EclipseJAVA调试器。

2008年11月11日星期二

Android开发步骤

在Eclipse上开发应用
为了在EclipseIDE上开发Andriod应用程序,你必须首先创建一个android项目,然后设置一个运行配置,你就可以编写、运行、调试你的应用程序。
以下提供的指导假设已经安装ADT插件。如果还没有安装ADT插件,你应该首先安装ADT插件。

创建Android项目
ADT插件提供一个新项目向导,该向导用于快速新建或者在已有代码基础上创建Eclipse项目,步骤如下:
1. 选择菜单 File > New > Project
2. 选择 Android > Android Project, 然后按Next
3. 在Contents下设置项目信息:
* 为了从新代码开始项目. 选择 Create new project in workspace
键入项目名称,基础包名称,单个活动类名称(以便创建一个JAVA桩文件),和用于你的应用程序的名字
* 为了从已存在代码开始项目,选择 Create project from existing source. 如果你打算基于SDK的简单例子创建并运行,你就使用这个选项. 例子应用程序存在于SDK的samples/ 目录
浏览包含已存在源代码的目录,然后点击OK. 如果该目录包含一个有效的manifest文件,那么ADT插件为你自动填充包、活动、应用程序名称
4. 选择 Finish.
ADT插件根据项目类型为你自动创建这些文件夹和文件:

* src/ 包含.java 活动文件
* res/ 包含资源.
* AndroidManifest.xml 项目的manifest文件

2008年11月6日星期四

android架构

android架构:

applications:
一套核心应用程序,包括:电子邮件客户端、短信程序、日历、地图、浏览器、通讯录等,所有应用程序使用JAVA开发。

Application Framework
开发人员拥有在applications中使用的API的完全使用能力。应用程序架构用于简化组件的重用,一些应用程序开放他们的功能API,另外一些应用程序使用那些功能API,但是会受限于框架规定安全约束。这些机制允许用户更换组件。
应用程序架构是一系列的服务和系统,包括:
(1)Views
提供一套丰富的扩展的视图,用于构建应用程序,包括:列表、表格、文本框、按钮、甚至嵌入式浏览器
(2)Content Provider
用于应用程序访问其他应用程序的数据,比如通讯录,或者,共享自己的数据
(3)Resource Manager
提供访问非代码的资源机制,比如本地化字符、图形、布局文件
(4)Notification Manager
为应用程序提供在状态栏显示自定义警告信息的能力
(5)Activity Manager
管理应用程序的生命周期,提供后退导航机制

Libraries
提供一套C/C++库,以供Andriod系统不同组件调用,库的开放途径是通过Application Framework,下面列举核心库:
(1)System C Library
基于BSD实现的C标准库(libc),专门针对嵌入式linux设备调整
(2)Media Library
基于PacketVideo的OpenCORE,这个库支持多数公共的视频音频格式的播放、录制,以及静态图片格式,包括MPEG4 H.264 MP3 AAC AMR JPG PNG
(3)Surface Manager
管理显示子系统的入口,无缝组合用于多应用程序的2D、3D图形层
(4)LibWebCore
一个现代Web浏览器引擎,该引擎增强andriod浏览器和嵌入式Web视图
(5)SGL
基本的2D图形引擎
(6)3D Libraries
一个基于OpenGL ES 1.0API的实现,该库使用硬件加速或者内含的高度优化的3D光栅刷新软件
(7)FreeType
位图、矢量字体渲染
(8)SQLite
用于所有应用程序的、功能强大的、轻量级关系数据库引擎

Android Runtime
Android包含一套核心库,该库提供能在核心JAVA语言核心库中获得的大多数功能。每个Android程序都运行在他自己的进程中,即Dalvik虚拟机的自主实例。Dalvik编写目的是:让一个设备能有效运行在多个虚拟机上。使用Dalvik执行文件格式(.dex)的Dalvik虚拟机针对小内存占用而优化。这个虚拟机是基于注册机制的,运行的类使用JAVA语言编译器编译,该编译器使用内置的DX工具转换成.dex文件格式。Dalvik虚拟机依赖LINUX内核,该内核提供诸如线程、低级别内存管理的基本功能

Linux Kernel
Android 基于提供诸如安全、内存管理、进程管理、网络堆栈、驱动模型功能的LINUX2.6。该内核也起着在硬件和软件堆栈之间的抽象隔离层的作用。

2008年11月4日星期二

android是什么

android是什么?
是用于移动设备一组软件。
包括开放式操作系统、中间件、关键应用程序。
android SDK提供在android平台上使用JAVA语言开发应用程序的工具和API

android特点:
1、Application Framework提供组件的复用和替换
2、Dalvik virtual machine针对移动设备最优化
3、Integrated browser基于WebKit引擎
4、Optimized graphics强力提供自建2D图形库,3D图形基于OpenGL ES 1.0规范
5、SQLite用于结构化数据存储
6、Meddia Support用于通用视频音频,更提供现有的图形格式支持,包括MPEG4, H.264, MP3, AAC, AMR, JPG, PNG, GIF
7、GSM Telephony使用硬件支持
8、Bluetooth,EDGE,3G,and WIFI使用硬件支持
9、Camera,GPS,compass(指南针),and accelerometer(加速计)使用硬件支持
10、Rich development environment包括设备模拟器、调试工具、内存和性能分析、eclipse插件

2008年11月2日星期日

转:Linux高性能计算集群

Linux高性能计算集群 - 概述

金戈 (jinge@cn.ibm.com), IBM软件工程师, IBM


1 集群

1.1 什么是集群

简单的说,集群(cluster)就是一组计算机,它们作为一个整体向用户提供一组网络资源。这些单个的计算机系统就是集群的节点(node)。一个理想的集群是,用户从来不会意识到集群系统底层的节点,在他/她们看来,集群是一个系统,而非多个计算机系统。并且集群系统的管理员可以随意增加和删改集群系统的节点。

1.2 为什么需要集群

集群并不是一个全新的概念,其实早在七十年代计算机厂商和研究机构就开始了对集群系统的研究和开发。由于主要用于科学工程计算,所以这些系统并不为大家所熟知。直到Linux集群的出现,集群的概念才得以广为传播。


对集群的研究起源于集群系统的良好的性能可扩展性(scalability)。提高CPU主频和总线带宽是最初提供计算机性能的主要手段。但是这一手段对系统性能的提供是有限的。接着人们通过增加CPU个数和内存容量来提高性能,于是出现了向量机,对称多处理机(SMP)等。但是当CPU的个数超过某一阈值,象SMP这些多处理机系统的可扩展性就变的极差。主要瓶颈在于CPU访问内存的带宽并不能随着CPU个数的增加而有效增长。与SMP相反,集群系统的性能随着CPU个数的增加几乎是线性变化的。图1显示了这中情况。



图1. 几种计算机系统的可扩展性

图1. 几种计算机系统的可扩展性


集群系统的优点并不仅在于此。下面列举了集群系统的主要优点:


  1. 高可扩展性:如上所述。


  2. 高可用性:集群中的一个节点失效,它的任务可以传递给其他节点。可以有效防止单点失效。

  3. 高性能:负载平衡集群允许系统同时接入更多的用户。

  4. 高性价比:可以采用廉价的符合工业标准的硬件构造高性能的系统。



1.2.1 集群系统的分类



虽然 根据集群系统的不同特征可以有多种分类方法,但是一般我们把集群系统分为两类:


  • 高可用(High Availability)集群,简称HA集群。这类集群致力于提供高度可靠的服务。

  • 高性能计算(High Perfermance Computing)集群,简称HPC集群。这类集群致力于提供单个计算机所不能提供的强大的计算能力。


2 高可用集群


2.1 什么是高可用性

计算机系统的可用性(availability)是通过系统的可靠性(reliability)和可维护性(maintainability)来度量的。工程上通常用平均无故障时间(MTTF)来度量系统的可靠性,用平均维修时间(MTTR)来度量系统的可维护性。于是可用性被定义为:



MTTF/(MTTF+MTTR)*100%


业界根据可用性把计算机系统分为如下几类:

表1. 系统可用性分类

可用比例



(Percent Availability)
年停机时间

(downtime/year)
可用性分类
99.53.7天常规系统(Conventional)
99.98.8小时可用系统(Available)
99.9952.6分钟高可用系统(Highly Available)
99.9995.3分钟Fault Resilient
99.999932秒Fault Tolerant


对于关键业务,停机通常是灾难性的。因为停机带来的损失也是巨大的。下面的统计数字列举了不同类型企业应用系统停机所带来的损失。

表 2. 停机给企业带来的损失

应用系统每分钟损失(美元)
呼叫中心(Call Center)27000
企业资源计划(ERP)系统13000
供应链管理(SCM)系统11000
电子商务(eCommerce)系统10000
客户服务(Customer Service Center)系统27000




随着企业越来越依赖于信息技术,由于系统停机而带来的损失也越拉越大。

2.2 高可用集群

高可用集群就是采用集群技术来实现计算机系统的高可用性。高可用集群通常有两种工作方式:


  • 容错系统:通常是主从服务器方式。从服务器检测主服务器的状态,当主服务工作正常时,从服务器并不提供服务。但是一旦主服务器失效,从服务器就开始代替主服务器向客户提供服务。

  • 负载均衡系统:集群中所有的节点都处于活动状态,它们分摊系统的工作负载。一般Web服务器集群、数据库集群和应用服务器集群都属于这种类型。



关于高可用集群的讨论很多,这里就不进行深入的阐述了。

3 高性能计算集群

3.1 什么是高性能计算集群

简单的说,高性能计算(High-Performance Computing)是计算机科学的一个分支,它致力于开发超级计算机,研究并行算法和开发相关软件。高性能计算主要研究如下两类问题:



  • 大规模科学问题,象天气预报、地形分析和生物制药等;

  • 存储和处理海量数据,象数据挖掘、图象处理和基因测序;


顾名思义,高性能集群就是采用集群技术来研究高性能计算。

3.2 高性能计算分类

高性能计算的分类方法很多。这里从并行任务间的关系角度来对高性能计算分类。



3.2.1 高吞吐计算(High-throughput Computing)


有一类高性能计算,可以把它分成若干可以并行的子任务,而且各个子任务彼此间没有什么关联。象在家搜寻外星人( SETI@HOME -- Search for Extraterrestrial Intelligence at Home )就是这一类型应用。这一项目是利用Internet上的闲置的计算资源来搜寻外星人。SETI项目的服务器将一组数据和数据模式发给Internet上参加SETI的计算节点,计算节点在给定的数据上用给定的模式进行搜索,然后将搜索的结果发给服务器。服务器负责将从各个计算节点返回的数据汇集成完整的数据。因为这种类型应用的一个共同特征是在海量数据上搜索某些模式,所以把这类计算称为高吞吐计算。所谓的Internet计算都属于这一类。按照Flynn的分类,高吞吐计算属于SIMD(Single Instruction/Multiple Data)的范畴。


3.2.2 分布计算(Distributed Computing)



另一类计算刚好和高吞吐计算相反,它们虽然可以给分成若干并行的子任务,但是子任务间联系很紧密,需要大量的数据交换。按照Flynn的分类,分布式的高性能计算属于MIMD(Multiple Instruction/Multiple Data)的范畴。

3.3 Linux高性能集群系统

当论及Linux高性能集群时,许多人的第一反映就是Beowulf。起初,Beowulf只是一个著名的科学计算集群系统。以后的很多集群都采用Beowulf类似的架构,所以,实际上,现在Beowulf已经成为一类广为接受的高性能集群的类型。尽管名称各异,很多集群系统都是Beowulf集群的衍生物。当然也存在有别于Beowulf的集群系统,COW和Mosix就是另两类著名的集群系统。


3.3.1 Beowulf集群


简单的说,Beowulf是一种能够将多台计算机用于并行计算的体系结构。通常Beowulf系统由通过以太网或其他网络连接的多个计算节点和管理节点构成。管理节点控制整个集群系统,同时为计算节点提供文件服务和对外的网络连接。它使用的是常见的硬件设备,象普通PC、以太网卡和集线器。它很少使用特别定制的硬件和特殊的设备。Beowulf集群的软件也是随处可见的,象Linux、PVM和MPI。



3.3.2 Beowulf集群和COW集群


象Beowulf一样,COW(Cluster Of Workstation)也是由最常见的硬件设备和软件系统搭建而成。通常也是由一个控制节点和多个计算节点构成。COW和Beowulf的主要区别在于:


  1. COW中的计算节点主要都是闲置的计算资源,如办公室中的桌面工作站,它们就是普通的PC,采用普通的局域网进行连接。因为这些计算节点白天会作为工作站使用,所以主要的集群计算发生在晚上和周末等空闲时间。而Beowulf中的计算节点都是专职于并行计算,并且进行了性能优化。它们采用高速网(Myrinet或Giganet)上的消息传递(PVM或MPI)进行进程间通信(IPC)。


  2. 因为COW中的计算节点主要的目的是桌面应用,所以它们都具有显示器、键盘和鼠标等外设。而Beowulf的计算节点通常没有这些外设,对这些计算节点的访问通常是在管理节点上通过网络或串口线实现的。

  3. 因为连接COW中计算节点的通常是普通的局域网,所以COW上的高性能应用通常是象SETI@HOME 这样的SIMD的高吞吐计算。而Beowulf无论从硬件、网络和软件上都对需要频繁交换数据的MIMD应用做了特别的优化。



3.3.3 Mosix集群


实际上把Mosix集群放在高性能集群这一节是相当牵强的,但是和Beowulf等其他集群相比, Mosix集群确实是种非常特别的集群, 它致力于在Linux系统上实现集群系统的单一系统映象SSI(Single System Image)。Mosix集群将网络上运行Linux的计算机连接成一个集群系统。系统自动均衡节点间的负载。因为Mosix是在Linux系统内核中实现的集群,所以用户态的应用程序不需要任何修改就可以在Mosix集群上运行。通常用户很少会注意到Linux和Mosix的差别。对于他来说,Mosix集群就是运行Linux的一台PC。尽管现在存在着不少的问题,Mosix始终是引人注目的集群系统。