2008年11月5日

双线性内插值法简单实现

图像缩放有几种常见的算法:最邻近插值(近邻取样法)、双线性内插值和三次卷积法,从得到的图像质量来说分别从低到高,从耗费的时间来看是从少到多。

Windows系统的函数StretchDIBits采用的是最邻近插值法,其运算速度最快,不过得到的图像质量也是惨不忍睹,下面是个对比:

frame_3.jpg2.JPG

原始图片为手机拍摄,size为320X240,右边是用windows自带的StretchDIBits放大两倍的结果,左边是采用双线性内插值法缩放的结果,注意观察图像中有斜线条的地方,最邻近插值法明显看到大量锯齿,而双线性内插值法则有效的消除了这些锯齿的产生。下面是转换函数代码,src为输入RGB数据(24位色),width和height为原始宽高,dest为输出的2倍大小的RGB数据。

void resize_rgbbuf(unsigned char * dest,unsigned char * src,int width,int height)
{
int sw = width - 1, sh = height - 1, dw = width*2 - 1, dh = height*2 - 1;

int B, N, x, y;
int nPixelSize = 3; // 24 color,3 bytes each pixel
BYTE * pLinePrev, *pLineNext;
BYTE * pDest;
BYTE * pA, *pB, *pC, *pD;


for ( int i = 0; i <= dh; ++i )
{
pDest = ( BYTE * )dest+i*width*2*3;
y = i * sh / dh;
N = dh - i * sh % dh;

pLinePrev = ( BYTE * )src+y*width*3;
y++;
pLineNext = ( N == dh ) ? pLinePrev : ( BYTE * )src+y*width*3;

for ( int j = 0; j <= dw; ++j )
{
x = j * sw / dw * nPixelSize;
B = dw - j * sw % dw;
pA = pLinePrev + x;
pB = pA + nPixelSize;
pC = pLineNext + x;
pD = pC + nPixelSize;
if ( B == dw )
{
pB = pA;
pD = pC;
}

for ( int k = 0; k < nPixelSize; ++k )
*pDest++ = ( BYTE )( int )(
( B * N * ( *pA++ - *pB - *pC + *pD ) + dw * N * *pB++
+ dh * B * *pC++ + ( dw * dh - dh * B - dw * N ) * *pD++
+ dw * dh / 2 ) / ( dw * dh )
);
}
}
return;

}


Full Text

2008年10月26日

西博会开了,我们堵了

今天是伟大的西博会开幕的日子,人民南路被封,而且事前没有任何通知,所有车辆被迫绕行。。。。。今天我上班晚了刚好30分钟,而且路上目睹了5起车祸,so powerful


Full Text

2008年10月21日

Finacial picture(wave picture from 1900 to 2008)

Dow-Cht-Flt-Str-021508-1150.gif


Full Text

I feel alone

I feel alone recent days,something happenned,something changed,maybe I changed also


Full Text

2008年10月19日

SVN服务器镜像简单设置(svnsync)

架设了svn版本服务器之后,为了保险起见通常需要对数据进行备份,使用svnsync进行版本镜像就是一种方式,也是我们采取的方式。

应用环境:本机有项目admin_project需要进行镜像,镜像目的地定为本机的项目admin_back(简单点好测试,实际应用时没有区别)

步骤:

1. 初始化。首先在本机建立项目admin_back,创建reposity,在conf目录中设置好权限并和密码。然后再hooks目录中建立一个文件pre-revprop-change.bat(Windows系统下为bat文件,Unix环境下不需要bat后缀,设置文件执行权限即可)。做完前面的工作后,执行svnsync进行初始化操作:

svnsync init svn://127.0.0.1/admin_back svn://127.0.0.1/admin_project

镜像目的地admin_back在前,镜像源admin_project在后。按照提示输入帐号密码,初始化工作就ok了。

2.进行同步操作,建立镜像。第一步只做了必要的初始化工作,将镜像项目和源项目关联到一起,但并没有做实际的文件同步操作,这步才会有实际的文件同步操作。执行命令:

svnsync sync svn://127.0.0.1/admin_back

前面已经将镜像目的和源进行了关联,所以这步命令中只需要指定镜像的目的即可。这步操作完成之后你就在admin_back 项目中有了项目admin_project的镜像。以后每次需要同步时执行这步的命令即可。

3.钩子自动同步(还未测试)。如果希望在每次提交时自动同步,则需要在原版本库增加post-commit脚本,内容如下:

echo off
svnsync sync --non-interactivesvn://127.0.0.1/admin_back

将上面的的内容存放为post-commit.bat(for win),然后放在源版本库项目admin_project下的hooks目录下,这样每次源版本库提交,都会引起镜像项目admin_back的同步


Full Text

2008年10月12日

SVN服务器初步架设步骤(For new guys only)

客户端:TortoiseSVN

服务端:svn-win32-1.5.0(http://svn.collab.net

第一次使用的人只需要建立最简单的功能,能够新建一个项目,能够check in和check out,知道服务端的几个配置文件的功能和位置以及设置方式,that would be a good start,let's go:

1. 下载工具软件。客户端的TortoiseSVN和服务端的svn-win32-1.5.0

2. 安装软件。客户端TortoiseSVN就傻瓜安装即可,无特殊设置;服务器端svn-win32-1.5.0不需要安装,下载后解包即可,执行程序位于bin目录下,我们可以建立一个批处理文件启动服务器,内容如下:

D:\svn-win32-1.5.0\bin\svnserve.exe -d -r c:\svnroot

上面的命令就是启动svn服务器,设置项目所在根目录为c:\svnroot

3. 新建一个项目。这涉及到服务器端和客户端两边的操作,分开说:

3.1 服务器端:

在c:\svnroot目录下新建一个目录用于存放项目,我们的为test_project,然后在新建的文件夹上右键->TortoiseSVN->create repository here,这会在该路径下建立新项目的文件结构和索引,包括conf、db、hooks、locks目录和两个文件format、readme.txt,其中conf目录下包含该项目的3配置文件:

authz:用户/组权限设置文件

passwd:用户密码设置文件,里面是以用户名、密码明码设置的

svnserve.conf:服务访问设置文件(仅用于该项目,此设置为每个项目独立的)

第一次学习使用无需设置authz和passwd(因为我们允许匿名访问,哈哈),修改svnserve.conf中的下面这行内容:

# anon-access = read

改为允许匿名访问:

anon-access = write

3.2 添加初始版本代码到新建的项目

服务端的架子已经搭好,但还没内容,开发人员工作的开始需要从服务器check out出来源代码的初始版本,这就是这步工作的内容。

从网络中任何一台机器(安装了客户端TortoiseSVN)开始导入源代码,架设源代码目录为our_source,在该目录上右键->TortoiseSVN->Import,URL of repository输入:svn://127.0.0.1/test_project(127.0.0.1表示其实我们是在本机测试,test_project为我们上一步在服务器根目录下建立的项目文件夹),然后确定,our_source目录下的所有文件都会被导入SVN服务器的test_project项目下,开发人员可以开始工作了。。。

3.3 从服务器上checkout出代码

现在可以从SVN服务器上check out出代码了。

首先新建一个目录用于存放自己的代码分支,我们新建一个目录branch1,然后在该目录上右键->SVN Checkout

现在我们的开发人员可以开始在所提供的源代码上开始工作了。

3.4 修改好后checkin代码

内容修改后你的目录会出现一个红色感叹号,你需要将你的修改提交给服务器,同样在该目录上选择右键->SVN commit,that's all

按照上面的步骤,你已经建立了一个最简单的SVN服务器,新建了一个项目,导入了一些内容,并且能够checkin和checkout,但这还不能真正开始工作,因为没有权限管理,任何人都可以访问你的SVN服务器,而且都还有写权限。要建立一个可以用于工作的SVN服务器,你还要修改服务器端项目文件夹下conf目录里的文件,关闭匿名访问,建立用户和组并设置权限。

PS:passwd文件设置用户帐号密码,authz文件设置用户组权限,svnserve.conf设置服务器行为,规则都很简单,具体可看例子或者随软件附带的帮助文件。authz文件中设置目录权限的格式为:

[enhance_project:/]
@enhance_project = rw
jz = rw


Full Text

2008年10月8日

hello again

hellohello again


Full Text

XP柔和的窗体设置

桌面上右键-》属性-》外观-》高级,项目选择桌面,点击颜色-》其他,进行自定义设置。


色调:85


饱和度:90


亮度:205


Full Text

2008年10月6日

mail blog testing

this post is from E-mail,it's fun!<span class="fullpost">also a full
text testing attached</span>


Full Text

summary test from offline blog editer(Raven)

this is summary


this is fulltext.


Full Text

full test testing

this is summarythis is the full tesxt


Full Text

离线发布Blogger的解决方案

blogger的发布API被伟大的GFW屏蔽了,只能通过代理或者类似途径对blogger进行离线发布,否则你就只能使用blogger的后台管理界面了,而我通常不喜欢每次都登录上去,我是个懒人。


首先感谢一位不知名的朋友,我是在他那里看到tor+Privoxy的组合的,:)


解决方法很简单:Tor+Privoxy组合,或者简单点使用Vidalia套件(组合了Tor和Privoxy以及一个firefox插件),我用的就是Vidalia。


步骤如下,非常简单和傻瓜:


1. 下载Vidalia


2. 安装Vidalia(默认即可,无需设置),安装完成后它应该会自动运行tor和privoxy。


3.将你的离线发布工具设置为使用代理,代理为127.0.0.1:8118(8118是Privoxy的本地代理端口)


That's all works you should do,全搞定,现在可以试试看了,have fun!


PS:美中不足的是,原来设置好的文章过长时收缩的功能搞忘了怎么用了,所以如果文章太长的话首页会显得很臃肿。
我又找回来了,可爱的fullpost标签


Full Text

我胡汉三又回来了

经历了注册安家blogger,对blogspot域名的不爽,然后在bplaced.net自己管理wordpress的快乐生活,接下来突然的blog被殃及池鱼的关闭(还好我有备份的好习惯),然后寻找一个满意的blog站点的艰难(我还是不喜欢live space),现在又回到了blogger(虽然我还是对blogspot的域名不爽)。。。。。。。。感谢Tor,感谢Privoxy,感谢Vidalia,感谢一切为网络通信作出贡献的人们,bless you all


唯一麻烦的是我想把在bplaced.net上的文章转过来会很烦


Full Text

2008年5月3日

blogger还是没有全部解除封锁

五一回家了一趟,家里用的是电信adsl,就像看看blog能不能访问,结果一试发现不行。看来blogger的封锁只是局部解除了,长宽可以,貌似教育网也可以,电信的adsl不行


Full Text

2008年4月28日

推荐一本小说--昆古尼尔

盛极而衰,科技和魔法的对抗引发浩劫,令旧时代的辉煌化作烟云。废墟上挺立起来的新文明无法摆脱过去的阴影,较量还在世界的背面悄然进行……

17k首发地址:http://www.17k.com/html/bookAbout.htm?bid=21225

个人比较喜欢这种,有点冷的西幻风格,语言又不是纯西幻那么硬。推荐一下,:)

PS:当了这么久的小白,老是看白书,也觉得有点对不起作者的劳动,这里推荐一下,也算能有点心安,bs自己中。


Full Text

我是一个硬盘

到处都能看到发人深省的文章,只要你仔细去回味....




很多事情是不是我们真的想要的,想过的生活到底是什么样子....




在每天的忙碌中,甚至上WC的时候还要带本书来看,我们到底得到了什么....




一直陶醉于所谓IT白领的称号,觉得自己是坐在高楼里的衣冠楚楚的上流人物,实际上还不如市井引浆卖车之流,不管是从生活质量还是收入水平上.....我们做的东西,究竟能让多少人受惠,有我家门口卖烧烤的老板满足的人多么?




这篇文章让我想起了东邪西毒,呵呵.其实很佩服能写这些东西的人,我怎么就写不出来呢






我是一个硬盘.




在一个普普通通的台式机里工作。别人总认为我们是高科技白领,工作又干净又体面,似乎风光得很。也许他们是因为看到洁白漂亮的机箱才有这样的错觉吧。其实象我们这样的小台式机,工作环境狭迫,里面的灰尘吓得死人。每天生活死水一潭,工作机械重复。跑跑文字处理看看电影还凑活,真要遇到什么大软件和游戏,上上下下就要忙的团团转,最后还常常要死机。




我们这一行技术变化快,差不多每过两三年就要升级换代,所以人人都很有压力而且没有安全感。每个新板卡来的时候都神采飞扬踌躇满志,几年光阴一过,就变得灰头土脸意志消沉。机箱里的人都很羡慕能去别的机器工作。特别是去那些笔记本,经常可以出差飞来飞去,住五星级的酒店,还不用干重活,运行运行word,上网聊聊天就行了。




但我更喜欢去那些大服务器,在特别干净明亮的机房里工作。虽然工作时间长点,但是福利好,24小时不间断电ups,而且还有阵列,热插拔,几个人做一个人的事情,多轻松啊。而且也很有面子,只运行关键应用,不像我们这里,什么乱七八糟的事情都要做。不过我知道,那些硬盘都很厉害,不是SCSI,就是 SCSI II,Fibrechannel,象我这样IDE的,能混到工作站就算很不错了。




我常常想,当年在工厂里,如果我努力一下会不会也成了一个SCSI?或者至少做一个笔记本硬盘。但我又会想,也许这些都是命运,不过我从不抱怨。内存就常常抱怨,抱怨他们主板部门的复杂,抱怨他如何跟新来的杂牌内存不兼容,网卡和电视卡又是如何的冲突。




我的朋友不多,内存算一个。他很瘦的而我很胖,他动作很快,而我总是很慢。我们是一起来这台机器的,他总是不停地说,而我只是听,我从来不说。




内存的头脑很简单,虽然英文名字叫Memory,可是他什么Memory都不会有,天大的事睡一觉就能忘个精光。我不说,但我会记得所有的细节。他说我这样忧郁的人不适合作技术活,迟早要精神分裂。我笑笑,因为我相信自己的容量。




有时候我也很喜欢这份工作,简单,既不用象显示器那样一天到晚被老板盯着,也不用象光驱那样对付外面的光碟。只要和文件打交道就行了,无非是读读写写,很单纯安静的生活。直到有一天……




我至今还记得那渐渐掀起的机箱的盖子,从缺口伸进来的光柱越来越宽,也越来越亮。空气里弥漫着跳动的颗粒。那个时候,我看到了她。她是那么的纤细瘦弱,银白的外壳一闪一闪的。浑身上下的做工都很精致光洁,让我不禁惭愧自己的粗笨。等到数据线把我们连在一起,我才缓过神来。开机的那一刹那,我感到了电流和平时的不同。后来内存曾经笑话我,说我们这里只要有新人来,电流都会不同的,上次新内存来也是这样。我觉得他是胡扯。我尽量的保持镇定,显出一副很专业的样子,只是淡淡的向她问好并介绍工作环境。慢慢的,我知道了,她,IBM-DJSA220,是一个笔记本硬盘,在老板朋友的笔记本里做事。这次来是为了复制一些文件。我们聊得很开心。她告诉我很多旅行的趣闻,告诉我坐飞机是怎么样的,坐汽车的颠簸又是如何的不同,给我看很多漂亮的照片、游记,还有一次她从桌子上掉下来的历险故事。而我则卖弄各种网上下载来的故事和笑话。




她笑得很开心。




而我很惊讶自己可以说个不停。




一个早晨,开机后我看到数据线上空荡荡的插口。她一共呆了7天。后来,我再也没有见过她。我有点后悔没有交换电子邮件,也没能和她道别。不忙的时候,我会一个人怀念伸进机箱的那股阳光。




我不知道记忆这个词是什么意思,我有的只是她留下的许多文件。我把它们排的整整齐齐,放在我最常经过的地方。每次磁头从它们身上掠过,我都会感到一丝淡淡的惬意。




但我没有想到老板会要我删除这些文件。我想争辩还有足够的空间,但毫无用处。于是,平生第一次违背命令,我偷偷修改了文件分配表。然后把他们都藏到了一个秘密的地方,再把那里标志成坏扇区。不会有人来过问坏扇区。而那里,就成了我唯一的秘密,我常常去看他们,虽然从不作停留。




日子一天一天的重复,读取写入,读取写入……我以为永远都会这样继续下去,直到一天,老板要装xp却发现没有足够的空间。他发现了问题,想去修复那些坏扇区。我拒绝了。很快,我接到了新命令:格式化。




我犹豫了很久 ……………………




track 0 bad,disk unusable



Full Text

制定好的日计划的七种武器

制定好自己的计划,并且努力实现,it's very important for everyone to grow up

一、确认今天大部分时间在做和你月目标、周目标相关的事情。

很多人忙忙碌碌,但是却从来不知道这些事情和自己的月目标有什么关系。所以苦劳一堆,功劳没有。

关注一下自己每天花在接近自己目标上面的事情到底有多少。



二、每天给自己时间不要超过7小时,14单元。

每天工作的计划时间不要超过7小时,由于机动事件的插入,基本上很难完成超过这个时间的工作。



三、选出最重要的三件事情先做完,再做其他事情。

每天先做最重要的事情能让你总是完成重要的东西,而不是被各种不重要的事情不断烦扰。

每天务必记得自己最重要的三件任务,使用手指记忆法。



四、 先出结果,再写任务。

先清楚的描述结果,再写需要完成什么任务。



五结果描述:数目可衡量、质量可描述、结果可交换。



数量质量可衡量:

描述的结果最好不要出现形容词,比如说“做好策划;练好听力;让大家觉得讲座不错。”

应该大量出现的是量词和动词。“完成不少于30页的策划书、获得领导的认同通过。”“完成听力练习的第二部分,确保自己听清所有的发音”“让学员通过讲座意识到……”。



结果可交换:

确保你的结果以大家能够理解的方式来呈现。

1. 整理信息形成文字。

2. 整理事件形成流程

3. 整理错误形成ETA



确保你的结果能让大家看到。(邮件、文字、会议等)



六、2分钟原则

如果完成这件事情的时间短于两分钟,不要写入计划,现在马上去做。



七、 7日剃刀

在工作表拖延超过7天的工作,

1. 现在马上做;

2. 如果做不了定出下一个关注日;

3. 如果已经不值得做(其实大部分属于此列)马上删除。


Full Text

Linux版GloMoSim的安装过程

我用的是Linux版的:
1.解压缩:
[root@testbox src]# tar -xzvf glomosim-2.03.tar.gz
2.创建目录/usr/local//parsec,拷贝与你的系统对应的parsec预编译包到/usr/local/parsec.我是redhat的系统,就拷贝redhat-7.2目录下的内容(当然你建立链接也可):

[root@testbox glomosim-2.03]# mkdir /usr/local/parsec
[root@testbox glomosim-2.03]# cp parsec/redhat-7.2/* /usr/local/parsec/
3.设置环境变量PCC_DIRECTORY,指向刚建立的/usr/local/parsec,并将pcc的路径加入PATH环境变量中去(最好加到profile中):
[root@testbox glomosim-2.03]# export PCC_DIRECTORY=/usr/local/parsec/
[root@testbox glomosim-2.03]# export PATH=$PATH:/usr/local/parsec/bin/
注意:导出PCC_DIRECTORY环境变量时目录后一定要加"/",否则会出错,我就在这里浪费了10多分钟,:(,没想到有这种低级错误发生.比如要指向的目录是/usr/local/parsec,那么你一定要写成 "/usr/local/parsec/",后面的"/"一定不能少.
4.到glomosim/main目录下,执行make:
[root@testbox main]# make
5.上一步make成功之后,你会在glomosim/bin目录下得到可执行文件glomosim,that's ok
6.你可以通过下面的步骤检查你的glomosim是否能正常工作:进入glomosim/bin目录,执行./glomosim config.in,会得到一个输出文件glomo.stat,把这个输出文件跟bin目录下的glomo.stat.sample比较,看看有无异常.



Full Text

Android学习系列之四--Anatomy of an Android Application

注:本系列文章原文内容来自http://code.google.com/android的介绍,每章之前会给出原始文章地址,主要为共享资源使用,欢迎教学用转载。用于商业用途请先联系作者。
Anatomy of an Android Application
原文:http://code.google.com/android/intro/anatomy.html
一个Android应用程序有四个组件:


 Activity
 Intent Receiver
 Service
 Content Provider
并非每一个应用程序都需要有所有的这四个组件,不过你的应用程序必须由其中的一个或者几个组成。
一旦你决定了你的应用程序需要其中的哪几部分,就要在AndroidManifest.xml文件中列出来。该文件是开发者宣告所用组件以及组件的功能和需求的,具体请参见相应文档http://code.google.com/android/devel/bblocks-manifest.html

Activity
Activity是Android程序四个组件中最常用的。一个Activity通常是你的应用程序中的一个单独的窗口,每个Activity都是有一个 Activity基类的扩展实现的。你的类由View组成,显示一个用户接口,并响应事件。大多数应用程序由多个窗口组成。比如,一个消息程序可能由下面几个窗口组成:一个显示联系人列表用以发送消息的窗口,另一个窗口负责写消息给指定的联系人,还有一个窗口用来浏览旧的消息或者修改设置。每一个这样的窗口都由一个Activity实现,从一个窗口移到另一个窗口通过启动一个新的Activity完成。在某些情况下,一个Activity可能给前面的 Activity返回一个值――比如一个让用户选择一个图片的Activity就要返回选择的图片给调用它的Activity。
当一个新窗口打开时,前面的窗口毁暂停,并被放入历史堆栈中,用户可以回退到之前打开的窗口去。当不需要继续保留时,窗口也可以选择被从历史堆栈中删除。Android会为每个从Home窗口启动的应用程序维持历史堆栈。
Intent and Intent Filters
Android使用一个特殊的被称之为Intent的类来从一个窗口移动到另一个窗口,一个Intent描述了应用程序想做什么事情。Intent的数据结构中两个最重要的部分是活动和活动之上的数据。活动的典型的值是MAIN(the front door of the activity),VIEW,PICK,EDIT等等,数据被表示为一个URI。比如,要想浏览一个人的联系信息,你需要创建一个具有VIEW活动的Intent,数据被设为表示该人的一个URI。
还有一个相关的类叫IntentFilter。当一个Intent是一个有效的要求做某些事的请求时,一个IntentFilter描述了一个活动可以处理的所有Intent。比如,一个可以显示联系人信息的Activity会公布一个IntentFilter,告诉外界它知道在得到表示个人信息的数据之后如何处理VIEW活动。所有的Activity都在AndroidManifest.xml文件中公开它们的IntentFilter。(这段话翻起来有点烦,总之大意是一个Intent类是包含数据和指定对数据操作的对象,Intent类会交给Activity类处理,Activity类会在自己的 IntentFilter类中宣告自己能处理哪些类型的活动,比如VIEW、EDIT,程序在将一个带指定活动的Intent传递给Activity之前应该检查该Activity是否能处理Intent中的活动)
在不同窗口之间切换是通过解析Intent完成的。比如,要想回到前面的窗口,一个Activity调用startActivity(myIntent) 函数。系统会查找所有安装的程序的IntentFilter,找出其中最符合myIntent的Activity,新的启动的Activity会被告知导致它被启动的Intent。整个解析Intent的过程发生在startActivity函数调用时,主要提供两个关键功能:
 Activity可以重用其它组件的功能,只需要简单的发出一个Intent格式的请求。
 Activity可以在任何时候被新的Activity替代,只需要声明与老的Activity一样的IntentFilter即可。

Intent Receiver
当你希望你的程序响应外部时间时可以使用IntentReceiver。例如,电话铃响,数据网络可用,或者时间到午夜。IntentReceiver不显示UI,不过如果有某些用户感兴趣的事情发生的话,它可以使用NotificationManager来通知用户。IntentReceiver在 AndroidManifest.xml文件中注册,你也可以在代码中使用函数调用Context.registerReceiver()来注册。要让 IntentReceiver起作用并不需要保持你的程序一直处于运行状态,当一个IntentReceiver被触发时,系统会在需要的时候启动你的程序。程序也可以给别的程序发送Intent广播,通过系统调用Context.broadcastIntent()实现。

Service
Service是长期运行并且没有UI的代码。一个不错的例子就是一个从播放列表播放音乐的媒体播放器。在一个播放器程序中,应该有一个或多个活动,允许用户选择歌曲并开始播放。不过,播放音乐本身并不需要被一个Activity处理,因为用户希望在到新的窗口时音乐仍然在后台继续播放。在这种情况下播放器Activity应该通过Context.startService()函数启动一个Service,这样就可以在后台继续播放音乐。系统会让音乐播放 Service持续运行,直到播放完毕。(可以阅读文档Android程序的生命周期http: //code.google.com/android/intro/lifecycle.html,了解更多关于Service的优先级的情况)另外,你可以与一个Service连接(或者当它没有运行时启动它),使用系统调用Context.bindSercice()完成。当连接到一个Service 时,你可以通过提供的接口与它通信。对音频播放Service来说,你可以完成暂停、回退等等功能。

Content Provider
程序可以在文件、SQLite数据库中存储数据,或者任何其它有效的方式均可。如果你想与其它程序共享数据的话,content provider就非常有用了。Content provider类是实现了一组标准方法接口的类,允许其它程序保存或者取回content provider中处理的数据。
更多关于content provider的信息,请参看介绍http://code.google.com/android/devel/data/contentproviders.html。


Full Text

Android学习系列之三--Hello Android

注:本系列文章原文内容来自http://code.google.com/android的介绍,每章之前会给出原始文章地址,主要为共享资源使用,欢迎教学用转载。用于商业用途请先联系作者。

Hello Android!

原文
程序员对一个新的开发环境的第一映象一般来自于经典的helloworld程序。在Android中,这是非常容易的,让我们看看该怎么做:

程序员对一个新的开发环境的第一映象一般来自于经典的helloworld程序。在Android中,这是非常容易的,让我们看看该怎么做:
 创建工程
 建立UI
 运行代码:Hello,Android
之后的小节详细讲了下面的内容:
 升级UI为XML布局方式
 调试
 在Eclipse之外创建工程
让我们开始吧!

创建工程
创建一个工程是很容易的事情,一个Eclipse插件(APE)提供了所需的功能。你需要安装了Eclipse 3.2或者3.3,同时也要安装APE插件。(下面的内容假设你已经安装了Eclipse和插件,如果没有请查看本系列手册之二,其中详细描述了安装插件的过程)
首先,我们先从全局看看建立“Hello,World!”工程的过程:
1. 通过File>New>Project菜单建立一个Android工程。
2. 在Android工程对话框中填写工程的细节信息。
3. 编译自动生成的源代码模板以便显示一些输出。
上面就是所有要做的工作,让我们进入每一步的细节来看吧。
1. 创建一个新的Android工程
在Eclipse环境中,选择File>New>Project。如果APE插件已经被成功的安装,那么会显示出下面的对话框:
http://static10.photo.sina.com.cn/orignal/53ba798343f55261b1749
在上面的对话框中选择“Android Project”,点击Next。
2. 填写项目详细内容
下面显示的对话框允许你输入工程的详细内容,这是一个例子:
http://static16.photo.sina.com.cn/orignal/53ba798306cbbb85f24ff
每个文本框的内容含义如下:
Project Name:
包含你所创建的工程的目录的名字。
Package Name:
包的名字空间――类似于Java语言――你所有的源代码都位于其下。This also sets the package name under which the stub Activity will be generated.
你的代码使用的包名必须在系统中所有包中是唯一的,不能重复。出于这个原因,为你的程序使用标准的域命名格式是非常重要的。在上面的例子中,我们使用域“com.google.android”,你可以根据你组织的情况选择一个不同的名字。
Activity Name:
这是APE插件要自动生成的stub类的名字,将会是Android的Activity类的一个子类。一个Activity就是一个可以执行并做一些事情的类,如果愿意它可以创建UI,不过并非必须。
Application Name:
这是你的程序的可读的title名字。

选择框“Use default location”允许你改变目录路径,指向你想要存储工程文件的地方。
3. 编辑自动生成的源代码
在插件运行之后,你会有一个名字叫HelloAndroid的类,其内容类似下面所示:
public class HelloAndroid extends Activity
{

@Override
public void onCreate(Bundle icicle)
{
super.onCreate(icicle);
setContentView(R.layout.main);
}
}
下一步将会开始修改这个文件!

建立UI
一旦你建立了工程,很明显下一步就是编写代码(the obvious next step is to get some text up there on the screen)。这里有一段完成的代码――后面我们将仔细解释每一行。
public class HelloAndroid extends Activity {

@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
TextView tv = new TextView(this);
tv.setText("Hello, Android");
setContentView(tv);
}
}
注意你需要添加下面的内容到代码之前,才能编译这个例子:
import android.widget.TextView;
在Android中,用户接口由等级继承的类View组成。一个View是一个可在屏幕上画出来的对象,比如比例调节按钮、动画,或者(在这个例子中)一个文本条。The specific name for the View subclass that handles text is simply TextView.
下面是一个创建TextView的例子:
TextView tv = new TextView(this);
传递给TextView的创建函数的参数是一个Android上下文实例,是一个系统句柄,提供了资源解析、数据库访问等服务。Activity类继承于上下文。因为我们的HelloAndroid类是Activiry的一个子类,它也是一个上下文,所以我们能把“this”引用传递给TextView。
建立了TextView之后,我们需要告诉它显示什么内容:
tv.setText("Hello, Android");
Nothing too surprising there。
到现在为止,我们建立了一个TextView,并且告诉它该显示什么内容。最后一步是将这个TextView与屏幕显示连接起来,就像下面:
setContentView(tv);
Activity类中的setContentView方法告诉系统将哪个View与Activity的UI联系到一起。如果Activity没有调用这个方法,就不会有UI显示出来,系统将显示一个空白屏幕。对我们来说,想显示一些文本,所以吧我们刚建立的TextView传给该函数。
好了,这就是我们的“hello,world!”!下一步当然就是,看看运行结果了,:)

运行代码:Hello,Android
Eclipse插件使得运行应用程序非常容易。通过选择Run>Open Run Dialog菜单选项,你可以看到类似下面的对话框:
http://static4.photo.sina.com.cn/orignal/53ba798306cbbb860a843
(下面是创建配置的内容,上面一节已经讲到了,有点基础的朋友应该都能轻松搞定,这里就省略了)
http://static4.photo.sina.com.cn/orignal/53ba798343f5533c824b3
这个图跟上一篇最后得到的差不多,不过上篇我没修改代码,所以是空白的,:)
注意:在运行或者调试Android程序,关闭仿真器之后,记得在任务管理器中关闭adb.exe,否则你下次运行的结果可能不正确,我就在这上面浪费了半个多小时,还纳闷呢。
升级UI为XML布局方式
上外面完成的“hello world”例子程序使用的是我们称之为“程序化”的UI布局方式,这种方式下你直接在源代码中建立UI布局。如果你有过很多UI编程经验的话,你可能会知道这种方式在某些时候可能是多么的脆弱:不居上很小的改动都可能导致很大的源代码修改,让人头痛。同时,也可能很容易搞忘记正确的将View连接在一起,而这会导致布局上的错误,浪费你调试代码的时间。
这就是为什么Android提供另外的UI布局方式的原因:基于XML文件的布局方式。最简单的解释可以通过一个例子进行,这里有一个XML布局文件,跟你刚刚完成的程序布局方式例子具有相同的效果:

android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="Hello, Android"/>

Android中通常的XML布局文件的结构比较简单。这是一个标签组成的树,每个标签是一个View类的名字。在这个例子中,是一个仅有一个 TextView元素的非常简单的树。你可以使用任何View类的扩展类作为标签名,包括在你自己的代码中定制的View类。这种结构使快速建立UI变得简单,使用比你源代码中简单的多的结构和符号完成。这种模式的创意来自于WEB开发模式,将应用程序的表现(UI)和逻辑分离开。
在本例中,有四个XML属性。下面是各个属性的简介:
xmlns:android
这是一个XML名字空间宣告,告诉Android工具你将会引用Android名字空间中定义的普通属性。每个Android布局文件的最外层标签都必须包含这个属性。
android:layout_width
该属性定义了View要占用的屏幕有效宽度。在本例中,这是我们唯一的View,所以我们让他占用整个屏幕,“fill_parent”表示这个意思。
android:layout_height
跟android:layout_width相同,只是它表示高度。
android:text
该属性设置TextView包含的文字信息。本例中,是我们的字符串“Hello,Android”。

这就是XML布局文件,但是它应该放在哪里呢?就在你的工程的res目录下。“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=0x7f020000;
};
public static final class layout {
public static final int main=0x7f030000;
};
public static final class string {
public static final int app_name=0x7f040000;
};
};
一个工程的R.java文件是对其中所有资源的索引,你可以在该类中方便的找到你工程中包含的资源。This is particularly powerful with the code-completion features of IDEs like Eclipse because it lets you quickly and interactively locate the specific reference you're looking for.
下载要注意的重要的事情是内层的名为“layout”的类,以及他的成员“main”。Eclipse插件会注意到你添加了一个新的XML布局文件,然后重新生成R.java文件。当你添加了其它资源时,也会看到R.java发生改变,与新内容保持一致。
最后需要做的是修改你的HelloAndroid源代码以便使用新的XML版本UI,替换刚才的硬编码的版本,下面是你的新类。正如你所看到的,源代码变得简单多了。
public class HelloAndroid extends Activity {

@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
}
}
当你做这个改变时,不要仅仅做拷贝粘贴,试试R类中的代码自动完成功能。你会发现这很有用。
现在你修改了代码,可以重新运行你的应用程序了――所有你需要做的仅仅是点击绿色的运行箭头,或者选择Run>Run Last Launched(没找到Run Last Launched,只有Run History??)。你将会看到跟之前同样的结果!毕竟,我们是要告诉你两种不同的布局方式实现同样的效果。
关于创建XML布局文件有非常多内容,不过那不是本小节要介绍的内容了。请看文档Implementing a User Interface(http://code.google.com/android/devel/implementing-ui.html)。

调试工程
APE插件同样也有优秀的与Eclipse继承的调试工具。为了展示这一点,让我们先在代码里加点错误进去。像下面这样,修改你的HelloAndroid源代码:
public class HelloAndroid extends Activity {

@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Object o = null;
o.toString();
setContentView(R.layout.main);
}
}
上面的改动简单的添加了一个空指针错误。如果你再次运行你的程序,会得到下面的结果:
http://static4.photo.sina.com.cn/orignal/53ba798343f5533f4fb13
为了找出哪里出了错,可以在你的代码中“Object o=null;”这行加入一个断点(可以双击Eclipse中该行代码左边的位置添加),然后选择Run>Debug Last Launched(还是没有找到Debug Last Launched,不过不影响我们调试,用Debug History选或者Open Debug Dialog选择均可)进入调试模式。你的程序将重新启动仿真器,不过这次他会在断点处挂起。然后,你可以在调试视图下单步执行你的代码,就像你调试其它任何程序一样。
http://static12.photo.sina.com.cn/orignal/53ba798343f5533f379fb

在Eclipse之外创建工程
如果你不使用Eclipse(譬如你更喜欢使用其它IDE,或者只喜欢使用文本编辑器和命令行工具),Eclipse插件就帮不了你的忙了。不过无需担心――你不会因为你不使用Eclipse而损失任何功能。
APE插件实际上只是一个Wrapper,包含了对Android SDK中一系列工具的使用(比如仿真器,aapt,adb,ddms等等,详情参见http://code.google.com/android/intro/tools.html)。因此,你完全可以用其它的工具包装这些必要的编译调试工具,比如一个ant build file。
Android SDK包含一个名为“activityCreator.py”的Python脚本,用来创建工程的所有的源代码和目录,以及一个ant兼容的build.xml文件。这允许你通过命令行建立你自己的工程,或者集成到你喜欢的IDE中去。
比如,要建立通过命令行一个跟上面的例子相同的Android工程,可以用下面的命令:
activityCreator.py --out HelloAndroid com.google.android.hello.HelloAndroid
要建立实际的工程,然后你需要运行命令“ant”。当成功运行之后,你会在bin目录下得到一个名为HelloAndroid.apk的文件。这个apk文件是一个Android包,可以使用adb工具在你的仿真器上安装和运行。
如果想了解关于这些工具的详细情况,请参见前面提到的文档,这是它的地址:http://code.google.com/android/intro/tools.html。





Full Text

Android学习系列之二--Installing the SDK

注:本系列文章原文内容来自http://code.google.com/android的介绍,每章之前会给出原始文章地址,主要为共享资源使用,欢迎教学用转载。用于商业用途请先联系作者。
Installing the SDK
原文
本小节讲如何安装Android开发包,设置你的开发环境。如果没有下载SDK包,可以通过下面的地址下载。
Download the SDK: http://code.google.com/android/download.html

本节内容如下:
系统和软件需求
安装SDK
安装Eclipse插件(ADT)
在Eclipse上开发Android应用程序
在其他的IDE上开发Android应用程序
Debugging
设备的Debug和Test设置
Debugging的小贴士
创建和安装Android应用程序
删除一个Android应用程序
Eclipse小贴士


系统和软件需求
想要使用Android SDK中的代码和工具开发Android应用,你需要一个合适的开发机器和环境,如下所述。
支持的操作系统:
Windows XP or Vista
Mac OS X 10.4.8或者更高版本(仅支持X86平台)
Linux(在Ubuntu Dapper Drake上测试过)
支持的开发环境:
Eclipse:
Eclipse 3.2,3.3(Europa)
Android Development Tool plugin(可选)
其他开发环境或IDE:
JDK5 or JDK6(只有JRE不行)
不和GNU的Java编译器(gcj)兼容
Apache Ant 1.6.5 or later for Linux and Mac,1.7 or later for Windows



安装SDK
下载完SDK包之后,将压缩包解压到本机的一个合适的地方。在本文的后面部分,我们将用$SDK_ROOT作为你安装SDK的目录。
为方便以后的开发,你可以把目录$SDK_ROOT/tools加到系统PATH中去:
在Linux下,编辑文件~/.bash_profile或者~/.bashrc,找到设置PATH环境变量的行,把$SDK_ROOT/tools加入其中。如果没有设置PATH的语句,可以加入下面的内容:
export PATH=${PATH}:<$SDK_ROOT/tools的真实路径>
在Mac机器上,在你的home目录下找.bash_profile,操作类似Linux下。如果你机器上没有这个文件可以自己创建一个。
在Windows机器上,右键单击我的电脑,选择属性->高级,点“环境变量”按钮,在出现的对话框中双击“系统变量”下面的Path变量进行修改,把$SDK_ROOT/tools的真实路径加入其中。
将$SDK_ROOT/tools目录加入系统路径中可以让你在使用adb(Android Debug Bridge)和其它命令行工具的时候不需要输入全路径名。如果你升级了你的SDK,如果和原来目录不一样的话,要记得更新你的PATH变量设置。



安装Eclipse的Plugin(ADT)
如果你希望使用Eclipse作为你开发Android应用程序的开发环境,你可以安装一个叫做ADT(Android Development Tools)的插件。ADT插件包含一系列功能强大的扩展功能,可以更快更容易的创建、运行并且调试Android应用程序。
如果你不打算使用Eclipse,那么就不需要下载和安装ADT插件。
为了下载和安装ADT插件,要先设置Eclipse远程更新站点,可以按照下面的步骤进行:
1. 启动Eclipse,选择菜单Help>Software Updates>Find and Install …


2. 在显示出的对话框中选择Search for new features to install,按下Next继续。


3. 按New Remote Site按钮。


4. 在出现的对话框中,为远程更新站点输入一个名字(譬如Android Plugin),还要输入下面的URL:
https://dl-ssl.google.com/android/eclipse/
按OK按钮。


5. 你现在会看到新的站点被加入到搜索列表中,并且被勾选上,按下Finish按钮。


6. 在消息更新结束后,你会看到Search Results对话框,在其中选中Android Plugin > Eclipse Integration > Android

Development Tools,然后按下Next按钮。


7. 接下来是插件的许可协议,看完之后选择Accept terms of the license agreement,然后按Next继续。


8. 在出现的Install对话框中按Finish,会开始下载ADT插件。

9. ADT插件没有认证,你可以点击“Install All”按钮允许安装。


10. 重新启动Eclipse。

11. 重启Eclipse之后,设置Eclipse的参数,使之指向开发包的根目录($SDK_ROOT):
a) 选择Window>Preferences…打开参数设置面板(在Mac OS X上:Eclipse>Preferences)
b) 在左侧面板中选择Android。
c) 点击右侧面板的SDK Location后面的地址栏中输入SDK包的地址,或者点击Browse按钮在系统中寻找。
d) 输入后点击确定。

更新ADT插件
可以通过下面的步骤更新ADT插件到最新版本:
1. 选择Help>Software Updates>Find and Install…
2. 选择Search for updates of the currently installed features,按Finish按钮。
3. 如果发现有ADT的更新的话,选中并且安装。
或者以下面的方式更形ADT插件:
1. 选择Help>Software Updates>Manage Configuration。
2. 从左侧树状导航条找到并选择Android Development Tools。
3. 在右侧的Available Task条目中点击Scan for Updates。


在Eclipse开发环境中开发Android应用程序
在Eclipse中开发Android应用程序之前,你需要先创建一个Android工程,然后设置启动配置。之后,你就可以写代码、运行和调试了。
本节之后的内容假定你已经在Eclipse中安装了ADT插件。如果你没有安装ADT插件的话,请先按照前面的步骤安装该插件。

创建Android工程
ADT插件提供了新工程向导,你可以快速创建一个Android工程。步骤如下:
1. 选择File>New>Project。
2. 选择Android>Android Project,按下Next按钮。
3. 选择两种不同的创建新项目方式:
 选择Create new project in workspace。创建新工程。
 选择Create project from existing source在已存在的代码上创建工程。你可以使用这个选项创建和运行SDK包中的例子代码,它们位于SDK包的samples目录下。
4. 点击Finish按钮,结束创建工程。
工程创建完后,ADT插件自动创建下面的文件和目录,放置特定的内容:
src/ :包含你的java源文件
res/ :包含资源文件
AndroidManifest.xml :工程的manifest文件

创建启动配置
在运行和调试Eclipse中的Android程序之前,必须先创建一个启动配置。启动配置定义了需要启动的项目,要开始的活动,仿真器选项等等。
通过下面的步骤创建启动配置:
1. 选择Run>Open Run Dialog…或者Run>Open Debug Dialog
2. 在左侧的树型工程类型列表中,右键单击Android Application,并选择New。
3. 在出现的对话框中输入你的配置的名字。


4. 在下面的Android表单中,点击Browse找到你的工程,选中要开始的活动。
5. 在Emulator表单中,设置想要的屏幕大小和网络状况。如果需要设置其它的仿真器选项,请参考

http://code.google.com/android/reference/emulator.html#startup-options
6. 可以在Common表单中设置额外的选项。
7. 点击Apply按钮,保存设置好的配置,或者点击Run或者Debug按钮。

运行和调试Android应用程序
现在你已经可以开始运行和调试Android程序了,Eclipse的使用就不多说了,:)下面这张图就是通过刚刚的步骤建立的helloandroid程序,虽然是空的什么功能都没有,不过看起来还是不错,有点苹果的风格。


下面的内容是讲在非Eclipse的IDE中开发的,还有一些tips,就不多翻译了,有兴趣自己看吧,以后有时间再补充,1点了,要洗洗睡了。



Full Text

Android学习系列之一--What’s Android

注:本系列文章原文内容来自http://code.google.com/android的介绍,每章之前会给出原始文章地址,主要为共享资源使用,欢迎教学用转载。用于商业用途请先联系作者。


What is Android?
原文
Android是一个为移动设备设计的软件平台,包括操作系统、中间件和一些关键应用。目前发布的Android SDK提供了必须的工具和进行应用开发所必须的API,在Android上的开发使用Java语言。

功能:
应用框架 支持组件重用和替换
Dalvik虚拟机 专为移动设备优化
集成的浏览器 基于开放源代码的WebKit引擎
优化的图象功能 一个定制的强劲的2D图象库,3D图象基于OpenGL ES 1.0(可选硬件加速功能)
SQLite 支持结构画的数据存储
多媒体支持 支持通常的音视频和图象格式(MPEG4,H264,MP3,AAC,AMR,JPG,PNG,GIF) (怎么就没有rm和wmv之类的,莫非斗争中。。。)
GSM电话 视硬件情况而定
蓝牙,EDGE,3G和WiFi 视硬件情况而定
摄像头,GPS,compass和accelerometer 视硬件情况而定
开发环境 包括一个设备模拟器,debug工具,内存和性能测试功能和一个Eclipse插件

Android系统架构
下图描述了Android的主要组件,每块都会在后面的说明中详细解释。
http://static2.photo.sina.com.cn/orignal/53ba798343eceb83b1a71

应用程序
Android将会一直一系列的核心应用,包括email客户端,SMS程序,日历,地图,浏览器,联系人等等。所有的应哟国内程序都使用Java编写。(其实在youtube上的Android Demo视频中已经可以看到这些功能的演示了,看起来相当的nice,:-),Youtube的Android Demo视频 )

应用框架
开发者开发自己的应用时可以调用核心应用所使用的相同的API接口。这个应用程序架构被设计用来简化组件的重用;任何应用都可以宣布它的功能,其他的任何应用都可以使用这些功能。相同的机制允许组件被用户替换。
背后的所有应用,是一套服务和系统,包括:
1.丰富并且可扩展的View System,可以用来简历应用程序,包括列表、表格、文本框、按钮,甚至包括嵌入的web浏览器。
2.Content Providers允许应用程序访问来自其他应用的数据(比如说联系人),或者共享它们自己的数据。
3. Resource Manager提供对非代码的资源的访问,比如本地化字串、图象、layout文件等。
4.Notification Manager允许所有的应用程序在状态条上显示定制的信息。
5.Activity Manager管理应用程序的生命周期,并且提供一个通用的导航回退功能(provides a common navigation backstack)
更多关于Android的详情,请看Writing an Android Application


Android包括了一套C/C++库,这些功能是通过Android应用框架提供给开发者的。下面是一些核心库:
1.系统C库 一个源自BSD的标准C库(libc),为基于Linux的嵌入式应用优化过。
2.多媒体库 基于PacketVideo的OpenCORE。支持许多流行的音视频格式的播放和录制,以及静态图象文件支持,包括MPEG4、H264、MP3、AAC、AMR、JPG、PNG、GIF。
3.Surface Manager 管理对显示子系统的访问,无缝的合成显示来自多个应用的2D和3D图象(seamlessly composites 2D and 3D graphic layers from multiple applications)
4.LibWebCore 一个web浏览器引擎,驱动Android浏览器和一个克嵌入的web view。
5.SGL 底层2D图象引擎
6.3D图象库 基于OpenGL ES 1.0 API的一个实现。该库可以使用硬件3D加速(如果硬件支持),也可以使用包含的高度优化的3D软件加速功能。
7.FreeType 位图和向量字体支持
8.SQLite 一个功能强大的轻量级关系数据库引擎
。。。。。。

Android Runtime
Android包括了一套核心库,提供Java核心库所提供的大部分功能。
每个Android应用程序在它自己的进程中运行,有它自己的Dalvik虚拟机的实例。Dalvik已经被改写过,使得一个设备可以有效得运行多个 VM。Dalvik虚拟机运行自己独特的可执行文件格式――.dex,该格式经过优化,使用尽量少的内存。虚拟机是基于寄存器的,运行被“dx”工具转化为dex格式的java代码。(The VM is register-based, and runs classes compiled by a Java language compiler that have been transformed into the .dex format by the included "dx" tool.)
Dalvik虚拟机依赖Linux Kernel提供底层功能支持,如线程、底层内存管理。

Linux Kernel
Android依赖Linux内核2.6提供核心系统服务,比如安全、内存管理、进程管理、网络、硬件驱动。Linux内核扮演的是硬件层和系统其他层次之间的一个抽象层的概念。


Full Text