安卓程序员求职信(精选多篇)范文
第一篇:安卓初级程序员
1、数学、物理、计算机相关专业本科学历;
2、熟悉计算机体系结构及计算机网络体系结构,了解c,c++或javaj2me其中一种语言;
3、对软件有较大兴趣,了解面向对象思维,有较强的逻辑思维能力及问题的解决能力;
4、熟悉linux系统编辑环境、测试流程;
5、熟悉tcp/ip、http协议,有操作系统的基础知识;oracle、mysql、sqlserver等数据库中至少一种;
6、有较强的沟通能力,并能主动的向上级汇报工作中出现的问题;
职位描述:
-负责公司android项目的软件开发
职位要求:
-扎实的java语言基础
-计算机相关专业本科学历
-具有较好的英文读写能力
-有移动平台开发经验的优先
-一年以上android手机开发经验
岗位描述返回公司简介 3000-3500元
1、数学、物理、计算机相关专业专科或以上学历;
2、 熟悉计算机体系结构及计算机网络体系结构,了解c,c++或javaj2me其中一种语言;
3、对软件有较大兴趣,了解面向对象思维,有较强的逻辑思维能力及问题的解决能力;
4、熟悉linux系统编辑环境、测试流程;
5、熟悉tcp/ip、http协议,有操作系统的基础知识;oracle、mysql、sqlserver等数据库中至少一种;
6、有较强的沟通能力,并能主动的向上级汇报工作中出现的问题;
软件测试
岗位职责/待遇/环境:
1、根据开发进度和任务分配,完成相应模块软件的测试任务;
2、进行编制项目文档和质量记录的工作;
3、能准确提出和定位软件缺陷;
4、能胜任回归测试的工作;
5、能与开发人员及产品人员有效沟通协作;
6、按时向上级汇报测试进度状况和数据。
录用流程:投递简历--初试笔试--录用签订就业协议--内部实训--上岗
工作地点:本职位工作地点在天津和北京
岗位要求:
1、计算机、通信、电子、数学等相关专业或者热爱编程,大学专科或以上学历;
2、熟悉web产品测试,熟悉b/s架构;
3、熟悉软件功能测试和兼容性测试;
4、熟悉软件开发的过程,有面向对象的软件开发思想;
5、对主流数据库如oracle/mysql/sqlserver有一定了解;
6、有较强的沟通能力和独立思考能力,工作细致;
7、具有高度的责任心和敬业精神,良好的团队合作精神。
录用流程:投递简历--初试笔试--录用签订就业协议--内部实训--上岗 工作地点:本职位工作地点在天津和北京
第二篇:安卓程序开发程序员培训的真实经历
安卓程序开发程序员培训的真实经历
大学毕业后,四年中的苦与乐都伴随着毕业的铃声而渐渐远去。毕业2年多之后,我辗转过2个行业,慢慢的,开始对自己的职业方向产生怀疑,看到和自己的同窗之间渐行渐远,渐渐找不到自己的方向,我开始陷入迷惘。偶然的机会,和同事们交流了解到安卓程序开发程序员培训,和安卓手机现在巨大的发展空间,并通过自己的了解和朋友的介绍,我发现这个行业是真正适合我的方向! android 是一个年轻的、有待开发的平台,它有潜力同时涵盖移动电话的两个不同消费群体,甚至可能缩小工作和娱乐之间的差别。于是,我毅然决定辞去原本还不错的工作,跟我的一个哥们从南方的家乡来到遥远的北京。我要来一次:重走青春!
初来到千锋学习安卓,感受到了与自学安卓程序开发不同的温馨和暖意。授课老师不仅给你传授专业的安卓程序开发程序员培训所要掌握的必备知识,而且课后会经常和同学们沟通和交流,并鼓励和引导大家更好的学习。经过了几个月的培训,我们和老师建立了深厚的友谊。老师每天开始上课前,会先复习前一天的知识,做到温故而知新。然后结合实例,现场演示教授当天的知识。并在课后留下相关的练习,让我们课后更好的消化和吸收。经过了复习,讲解和练习的过程,对知识有了更深的理解。在经过每个阶段性学习之后,是项目实战。我觉得这是个人能力提高最快的时候。老师会给予真实的项目开发文档和案例,采用小组分配的方式,充分调动每一位学员的思考和动手能力,真实体会公司实际的开发场景。
除了自己的坚定选择,最需要感谢的就是这里的老师和课程体系,还有我可爱的朝夕相处过共同为了安卓程序开发而拼搏过的同窗们。
我能有今天的一份成绩,站在这样的一个位置,不只是薪资,也不仅仅是在安卓程序开发程序员培训机构学习的短短四个月就能决定的这一切。更主要的是收获了属于自己的一个平台,认识了更多的朋友,让我有能去挑战移动互联网,成为一名真正的安卓程序开发程序员,并能在安卓程序开发的路上,开创属于自己人生中的新起点。
在这里,勤奋的人们开始了更加勤奋的对目标的追逐。逐渐的,我从一个对android程序开发的初窥,到学会再到深入理解和掌握,继而赢得一次次反思,每一次都是不断的充实自己的过程。在这里学习android程序开发程序员培训的过程中是苦并快乐的,每当解决了一个新的问题,就感觉离自己的梦想又近了一步,也对android程序开发又多了一个更深层次的理解。
第三篇:程序员求职信
程序员求职信2
发布时间:2014年09月03日 来源:应届毕业生求职网
个人简历简历模板英文简历个人简历模板求职简历
个人简历表格简历范文简历封面简历表个人简历范文
本文系程序员求职信模板,仅供参考。
个人基本资料
出生日期:1982-06-12 性别:女
婚姻状况:未婚 身高: 厘米
体重: 公斤
求职意向描述_应聘岗位:计算机专业人员/系统分析员/软件/软件测试工程师/internet开发工程师/通讯类专业人员
岗位描述:软件程序员,c程序员,c++程序员,java程序员,it客户销售人员和行政管理 工作经验:0 年 期望月薪:
教育背景
毕业学校
重庆邮电学院 最高学历:本科 专业:计算机科学与技术(软件工程)电脑水平:优秀 外语语种:英语 外语水平:良好
教育历程:
毕业于重庆邮电学院
工作简历
在校应届毕业生
个人能力及自我介绍
本人性格乐观开朗,自信大方,正直不讹,原则性强,直率诚恳,坦然豁达,爱好广泛。大学四年的刻苦学习生活,德、智、体全面发展。在学习期间严格遵守学校各项规章制度,学习态度端正,多次获得校优秀学生奖学金、“优秀干部”的称号。在学习上通过课外学习不断完善自己。对待工作热情,与同学关系融洽,积极参加学校文体活动,获得了一定的成绩,受到了老师和同学们的肯定。在这四年中,不仅能让我在这样广阔的知识土壤里吸取了不少的养份,同时,还培养了我独立坚韧,团结互助的素质品质,使自己有一定的工作能力,组织能力,社交能力,以及语言沟通能力。
程序员求职信模板
发布时间:2014年07月12日 来源:应届毕业生求职网
英文求职信模板中文求职信模板个人求职信模板会计求职信模板求职信
求职信范文英文求职信求职信怎么写求职信名称求职信格式
本文系程序员求职信模板,仅供参考。
个人基本资料
出生日期:1982-06-12 性别:女
婚姻状况:未婚 身高: 厘米
体重: 公斤
求职意向描述_应聘岗位:计算机专业人员/系统分析员/软件/软件测试工程师/internet开发工程师/通讯类专业人员
岗位描述:软件程序员,c程序员,c++程序员,java程序员,it客户销售人员和行政管理 工作经验:0 年 期望月薪:
教育背景
毕业学校
重庆邮电学院 最高学历:本科 专业:计算机科学与技术(软件工程)
电脑水平:优秀 外语语种:英语 外语水平:良好
教育历程:
毕业于重庆邮电学院
工作简历
在校应届毕业生
个人能力及自我介绍
本人性格乐观开朗,自信大方,正直不讹,原则性强,直率诚恳,坦然豁达,爱好广泛。大学四年的刻苦学习生活,德、智、体全面发展。在学习期间严格遵守学校各项规章制度,学习态度端正,多次获得校优秀学生奖学金、“优秀干部”的称号。在学习上通过课外学习不断完善自己。对待工作热情,与同学关系融洽,积极参加学校文体活动,获得了一定的成绩,受到了老师和同学们的肯定。在这四年中,不仅能让我在这样广阔的知识土壤里吸取了不少的养份,同时,还培养了我独立坚韧,团结互助的素质品质,使自己有一定的工作能力,组织能力,社交能力,以及语言沟通能力。
尊敬的领导:
您好!得知贵公司的招聘信息,我对flash程序员一职很感兴趣。从大学毕业至今,一直在深圳一家网络公司担任flash编程职务。对flash游戏课件编程有了相当的了解和熟悉,我相信我有能力担当贵公司所要求的flash编程任务。
我对计算机编程有着非常浓厚的兴趣,熟练运用flash动画及action script2.0编程,熟悉flash游戏开发流程;熟悉photoshop、dreamweaver mx 2014及visual studio 2014等网页制作工具,熟悉html,有一定的.net+sql网站建设能力。
面对当今激烈的人才竞争,我很清楚自己知识有限,但我更清楚我有着不甘落后的精神和不断学习,不断提高的愿望。乐于进取,不怕挫折是我的人生信条,给我一次机会,让我去实
践,去闯,去干,因为能力要在实践中培养,也终究要在实践中体现。我信心十足,相信我所具备的专业技能,积累的知识,加上有良好的人际关系,会帮助我掀开生活中的新一页。 假如我有幸能成为贵公司的一员,我相信我有能力胜任贵公司安排的工作,并愿与公司同甘共苦,并将以敬业乐业,深入实际,吃苦耐劳,开拓创新的精神投入到工作当中去。我相信贵公司能给我提供施展才能的另一片天空,而且我也相信我的努力能让贵公司的事业更上一层楼。感谢您对我的关注!
此致
xxx
2014年11月20日
尊敬的领导:
您好!
我来自xxxxxx学院xxxx系xx技术xx班的学生,我将于明年7月完成大专学业,真正步入社会,开始人生路上的新一段征程。
我这次写求职信的目的是应聘贵公司的c#程序员。
两年多来,在校领导和老师的引导下,我努力很认真的学好专业知识,训练专业技能,专业水平每一年都有明显提高。在校期间,我学习了c语言,java,c#,winform,sqlserver,oracle,有较强的实践能力。
两年半的大专生活教我学会了冷静的思考问题、以及如何面对问题,使我能在人生的坐标上找寻适合自己的位置并不断修整自我,更让我深刻认识到人要用心地去做每一件事,认真、踏实地面对人生的每一步。所以我诚挚地希望加入你们这支优秀的、富有生命力的群体,在大家的指导和帮助下,共同携手,在人生的道路上不断进取。
“天生我材必有用”,后附本人的简历,希望贵公司能给我一个发展的平台,我会好好珍惜它,并全力以赴,为实现自己的人生价值而奋斗,为贵公司的发展贡献力量。
此致
敬礼!
该信息出自应届毕业生求职网yjbys.com:http://
下面就是一则典型的求职信,让我们一起来看看怎样才能写出一封成功的求职
信。
求职信范例:
xx经理:
您好!
我写此信应聘贵公司招聘的经理助理职位。我很高兴地在招聘网站得知你们的招
聘广告,并一直期望能有机会加盟贵公司。
两年前我毕业于首都经济贸易大学国际贸易专业,在校期间学到了许多专业知识,如国际贸易,国际贸易实务,国际商务谈判,国际贸易法,外经贸英语等课程。毕业后,就职于一家外贸公司,从事市场助理工作,主要是协助经理制定工作计划、一些外联工作、以及文件、档案的管理工作。本人具备一定的管理和策划能力,熟悉各种办公软件的操作,英语熟练,略懂日语。我深信可以胜任贵公
司经理助理之职。
个人简历及相关材料一并附上,希望您能感到我是该职位的有力竞争者,并希望
能尽快收到面试通知,我的联系电话:139********
感谢您阅读此信并考虑我的应聘要求!
此致敬礼!
您真诚的朋友:
xxxx年x月x月
第四篇:程序员求职信
尊敬的领导:
您好!
感谢您在百忙之中拔冗阅读我的求职信。扬帆远航,赖您东风助力!我是广西大学2014届软件工程专业的本科毕业生。值此择业之际,我渴望能到贵单位供职。希望与贵企业的同事们携手并肩,共扬希望之帆,共创事业辉煌!
宝剑锋从磨砺出,梅花香自苦寒来。在大学期间,我以勤勉进取的积极心态,全方位地充实锻炼自己,经过学习和磨练,我具备了以下三个方面的品质能力:
一、诚实正直、勤劳务实的人格品质。人格既包括一个人的性格,又包括一个人的道德品质。在大学,我不仅学到了课本里的知识,更领悟到了课堂以外做人做事的道理。优秀的人格品质是一个人内在修养的外在表现。在当下,这是一种文明的社交方式,是顺利开展工作、建立良好社交关系的基石。
二、扎实的专业基础知识和较强的自学能力。具备扎实的c/c++语言基础,数据结构、算法等相关知识,对面向对象编程有较高层次的认识,具有良好而规范的编程习惯和技术文档编写习惯。我还积极将所学知识学以致用,在业余时间完成了电信计费系统、playfair和维吉尼亚加密演示系统和俄罗斯方块的代码编程。此外,在校期间学习上锐意进取,专业成绩优异,以650分通过英语四级,曾多次荣获国家奖学金及荣获校优秀学生奖学金。
三、突出的工作能力和强烈的团队合作精神。学习之余,我很注重知识与能力的平衡。在校担任校党委组织部助理、院实践调研部部长、支部书记等职务,多次策划组织或参与校内外的志愿活动,如党员服务月活动、社区电脑培训、党员募捐仪式等。这培养了我强烈的责任感、良好的交流沟通能力和组织协调能力,增强了团队合作意识,同时也使我积累了一些社会经验。
十年寒窗的求学生涯使我形式了优良的处事作风和先进的思想观念,并有独特的思维方式和和谐的人际关系。我时刻注意抓住机会锻炼自己,并时刻思索做好工作的方法。我是一个有能力且有团队精神的人,对工作满怀热情,我相信自己能在新环境既定的团队中做好工作。
期望我能适合您的要求,也期望您选择我,您的选择就是我的希望。为了方便您更详细地了解我的情况,请审阅我呈上的简历。期望能得到您的回音!祝贵企业事业蒸蒸日上、硕果累累!
此致
敬礼!
自荐人:**
2014年5月14日
第五篇:安卓学习心得
android学习心得
-----093380117计算机应用(1)张峰
1.关于activity
1. 在一个activity中使用多个view
如果把activity看作mvc中的control?它负责管理ui和接受事件(包括用户的输入),虽然说一个activity通常对应一个屏幕,但事实上,我们是可以只用一个activity管理多个不同的view来实现简单的逻辑。
首先,我们增加一个新的资源描述layout/second.xml。
除了一个“hello中国”以外,增加一个按钮可以返回前一个界面。然后,在代码中我们要为hellotwo增加两个方法,setviewonecommand和setviewtwocommand,分别处理一下在不同界面时,从资源里加载组件并为组件绑定一个事件处理器最后,我们需要在oncreate的时候,也就是启动后的main界面上设置一下按钮事件处理器。
2. 还是回到正道上,多个activity之间的跳转
android中提供一个叫intent的类来实现屏幕之间的跳转,按文档的说法,似乎他们也建议采用这种方法,intent的用法比较复杂,现在我先看看它最简单的用法。
这里的跳转功能用intent来操作,它的最简单用法就是用函数setclass()设置跳转前后两个activity类的实例,然后调用activity自己的startactivity(intent)即可。最后一句finish()表示将当前activity关掉(如果不关掉会如何?你可以自己试一下看效果,事实上有时我们是不需要关掉当前activity的)。
然后,我们同样弄一个activity类hellothreeb,代码与前面的差不多,只是将setclass的两个参数反一下,这样就可以简单地实现在两个activity界面中来回切换的功能了。
2.关于 intent的使用
intent分为两大类,显性的(explicit )和隐性的(implicit)。一般来说,intent要定位事件的目的地,无外乎需要以下几个信息:
1.种类(category),比如我们常见的 launcher_category 就是表示这是一类应用程序。
2.类型(type),在前面的例子中没用过,表示数据的类型,这是隐性intent定位目标的重要依据。
3.组件(component),前面的例子中用的是setclass,不过也可以用setcomponent来设置intent跳转的前后两个类实例。
4.附加数据(extras),在contenturi之外还可以附加一些信息,它是bundle类型的对象。
其实,如果是在一个应用内部,这种隐性的intent实在有点别扭,个人觉得,这种松藕合的实现方法,只适用于那些较大的系统或者多个不同的应用之间的调用,可手机上又有什么“较大”的系统呢?无非是可以与不同来源的多个应用之间方便地互操作而已,那么会是什么样的场景呢?比如,给qq好友发送gmail邮件,用googlemap查找qq好友所在的位置?看上去挺不错的。
关于这个contentprovider,其实还有话说,它主要是的那些看似数据库操作的方法我们都没真正去实现呢。不过今天就到这里了,等下回再去研究吧。
3.关于listactivity
准备一个list对象并借助adapter就可以构造出一个列表。重载onlistitemclick方法可以响应选择事件,利用第一个参数可以访问到这个listview实例以得到选中的条目信息。这里有一点要说明的,就是如果更简单的话,其实连那个setcontentview都可以不要了,android也会自动帮我们构造出一个全屏的列表。但是本例中我们需要一个textview来显示选中的条目,所以我们需要一个layout.mainb描述一下这个列表窗口。
这里需要注意的是那个listview的id,是系统自定义的android:list,不是我们随便取的,否则系统会说找不到它想要的listview了。然后,在这个listview之外,我们又增加了一个textview,用来显示选中的条目。
再来说说这里用到的arrayadapter,它的构造函数中第二个参数是一个资源id,arrayadapter的api文档中说是要求用一个包含textview的layout文件,平台用它来显示每个选择条目的样式,这里的取值是r.layout.list_row,所以,我们还有一个list_row.xml文件来描述这个布局,相当简单。
从arrayadapter上溯到baseadapter,发现还有几个同源的adapter也应该可以使用,象simpleadapter和cursoradapter,还是做个例子来实验一下吧。
然后,在hellotwob中的oncreate函数中,修改代码,有几个不同:items的元素是hashmap实例,这是一点变化,然后构造函数除了要求items以外,还要求提供一个string[]来说明用hash表中的哪个字段显示在列表中,而后是一个资源id的数组。
因为单纯的cursoradapter是抽象类,所以我用的是它的子类simplecursoradapter,很好理解,先用contentresolver查询通讯簿得到一个游标,然后告诉simplecursoradapter要用其中的people.name作为显示项来构造出一个adapter即可。
4.关于dialog
注意到android.app包下除了dialog(可用于制作复杂的对话框)以外,还包括了几个系统定义好的对话框类,如datepickerdialog、timepickerdialog及alertdialog。
其中alertdialog我上回用过一次,基本上就那样子了,今天看看另外两个对话框的使用吧。
很简单的,无非(请你收藏好 范 文,请便下次访问WWW.HaoWoRD.com)是需要一个ondatesetlistener接口的实现而已,在它里面的dateset方法中就可以得到选择的日期了。而timepickerdialog与datepickerdialog使用如出一辙。
看看另一个progressdialog的用法吧,这个类与alertdialog一样包含了多个static的方法,所以使用起来是非常方便的。比如说,如果我们需要用它来表示一个长时间的操作。
5.关于service和notification
大略地看了一下android.app下的service类,觉得它与activity非常相似,只是要注意几个地方:
1.生命周期,service的从oncreate()->onstart(int,bundle)->ondestroy()显得更为简单。但是它的onstart是带参数的,第一个id可用来标识这个service,第二个参数显示是用来传递数据的了。比较activity,传递数据的bundle是在oncreate就带进入的。
2.service的启动由context.startservice开始,其实activity或者service都是context的派生类。结束于context.stopservice()或者它自己的stopself()。
3.service还有一个与activity不一样的是它可以由另一个context去绑定一个已存在的service。就是这个方法context.bindservice(),被绑定的service要求是已经oncreate了但可以没有onstart。在service类中有个抽象方法getbinder()可以得到这个ibinder对象。关于这方面的细节,以后再看,这里只做个记录罢。
4.与service有关的还有一个安全的问题,可以在androidmanifest.xml中用<uses-permission>标签来声明一个service的访问权限,关于android的安全问题也留待以后再解决吧。
6.gridview与imageview
简单一点吧,就瞧瞧那个grid的效果,android提供了一个gridview,不过从apidemo中看来,它似乎与pc上的grid差别还是挺大的,更像那个iconview的感觉。不知道android中如何实现表格界面?虽然在移动终端上,表格一般不会有谁使用,大家似乎更倾向于使用listview,而android对于listview则有更简单的实现listactivity。
很简单,只要重载几个方法就可以了,关键是那个getview方法,它负责构建出每个单元格中的对象实例。这里我们构造的是一个imageview实例。
然后就是同样的将这个adapter赋给gridview即可,大家可以看看效果,注意在做这个例子前,先放几个小图片到res/drawable目录下,buildproject一下就可以得到那个r.drawable.a了(这里的a是图像文件名,如a.png)。
在getview方法中我们使用了imageview类,这又是一个widget。除了上面用到的几个方法以外,还有以下几个方法值得注意:
与图像来源有关的方法,我们只用了资源文件的方式。
还是习惯性跑题了,其实,我是想通过我对这个类的无数次debugger跟进,说说它的多线程异步处理的解决策略的。他的基本策略如下:
1. 当你实例化一个asyncqueryhandler类时(包括其子类...),它会单件构造一个线程(后面会详述...),这个线程里面会构建一个消息循环。
2. 获得该消息循环的指针,用它做参数实例化另一个handler类,该类为内部类。至此,就有了两个线程,各自有一个handler来处理消息。
3. 当调用onxxx的时候,在xxx函数内部会将请求封装成一个内部的参数类,将其作为消息的参数,将此消息发送至另一个线程。
4. 在该线程的handler中,接受该消息,并分析传入的参数,用初始化时传入的contentresolver进行xxx操作,并返回cursor或其他返回值。
5. 构造一个消息,将上述返回值以及其他相关内容绑定在该消息上,发送回主线程。
6. 主线程默认的asyncqueryhandler类的handlemessage方法(可自定义,但由于都是内部类,基本没有意义...)会分析该消息,并转发给对应的onxxxcomplete方法。
7. 用户重写的onxxxcomplete方法开始工作。
这就是它偷偷摸摸做过的事情,基本还是很好理解的。我唯一好奇的是它的线程管理方式,我猜测他是用的单件模式。第一个asyncqueryhandler的实例化会导致创建一个线程,从此该线程成为不死老处男,所有的contentresolver相关的工作,都由该线程统一完成。个人觉得这种解决方式很赞。本来这个线程的生命周期就很难估量,并且,当你有一个contentprovider的请求的时候,判断你会做更多的类似操作并不过分。就算错了,花费的也只是一个不死的线程(与进程同生死共存亡...),换来的却是简单的生命周期管理和无数次线程生死开销的节约。同时另外一个很重要的问题,他并会涉及到单件中数据同步的问题,每个类都有各自的handler类,彼此互不干扰,分发可以分别进行。当多个数据请求的时候,在同一个contentresolver上进行的可能微乎其微,这就避免了堵塞。总而言之,这套解决办法和android的整体设计算是天作之合了。
所以建议,如果你有什么非contentprovider操作,却需要异步多线程执行的话,模拟一套,是个不错的策略,当然,具体情况具体分析,生搬
硬套是学不好马列主义的。
7.显示控件使用
android的界面显示同样也是基于控件的。通常是用view(包括viewgroup)控件配上xml的样式来做的。具体细节不想说了,可以参考 samples里的apidemos/view,和view的doc,以及implementing a ui这篇doc。其他还有很多,感觉算是sdk讲述的最多的内容。
从控件的使用上,和网页的设计类似,尽量用parent_width之类的抽象长度,用theme来做风格,抽取所有的字串等信息做本地化设计。相关内容参看implementing a ui就好。
一类比较重要的是数据绑定控件。如果做过asp.net会从中看到很多类似的地方。一个支持数据绑定的控件,比如listview。可以通过一个 listadapter绑定到一个数据源上。listadapter是一个抽象类,主要的实现类包括simpleadapter和 simplecursoradapter。前者是绑定一个静态的array,后者是绑定一个动态的cursor。cursor前面说过,是一个指向数据源的随机迭代器,将view绑定到cursor通常要设置这样几个参数。一个是每一行的样式,称作row layout,其实就是一个普通的layout的xml文件。还有就是一个列和现实控件的对应关系。那个控件显示哪个列的值,这是需要配置的。为了定制一个良好的数据显示控件,最简单你可以定制很pp的row layout,复杂一点就是可以重载绑定控件view,或者是适配器listadapter。如果是一个数据显示密集的应用,且你对ui有些追求,这个工作估计是必不可少的。
一个主要用于显示数据内容的activity,可以选择派生自listactivity。它提供了一个具有listview 的layout,还有simple_list_item_1, simple_list_item_2, two_line_list_item等默认的row layout,还有一些比较不错的api,和可供响应选择item的事件。可以满足你比较基础的需求。如果你觉得只有一个listview的界面太突兀,你可以为这个listactivity指定一个layout,需要注意的是,你需要提供一个id为@android:id/list的listview控件,避免activity在内部偷偷寻找该控件的时候失败。
除了这些要求,做好ui还有注意易用性和效率。快捷键是一个比较不错的选择,在 activity中调用setdefaultkeymode(shortcut_default_keys),可以开启快捷键模式,然后你可以将菜单绑定到指定快捷键上就ok了。个人觉得tip也是一个比较重要的东西,但目前观察看来,这个东西只能够自己提供了。界面的动态性有时候是不可避免的,比如说菜单就是一个需要经常根据光标位置提供不同的选项。这个东西android很人道的考虑到了,你可以参看nodelist这个sample。它采取的应该是一个静态模拟动态的方式,这样有助于提高速度。你也可以利用viewinflate,动态从一个xml创建一个控件。成本据doc说很大,不到万不得已不要使用。
8.intent消息传递
在前面写android的contentprovider时候,可以看到那是基于观察者模式的一个消息传递方法。每一个cursor、contentresolver做为一个小的注册中心,相关观察者可以在这个中心注册,更新消息由注册中心分发给各个观察者。而在mfc或winform中,都会形成一个消息网,让消息在网中流动,被各节点使用、吃掉或者在出口死掉。
相比之下,我个人觉得基于intent的android核心消息传递机制是有所不同的。它应该会有一个全局性的注册中心,这个注册中心是隐性的,整个android系统中就那么一个。所有的消息接收者,都被隐形的注册到这个中心。包括activity,service和intentreceiver。其实说隐形注册是不确切的,所有注册都还是我们手动告诉注册中心的,只是与传统的方式不一样,我们通常不是通过代码,而是通过配置文件来做。在应用的manifest中,我们会为一些activity或service添加上intent-filter,或在配置文件中添加<receiver></receiver>项。这其实就相当于向系统的注册中心,注册了相关的intent-filter和receiver(这个事情完全可以通过代码来做,只是这样就失去了修改的灵活性)。
当程序有一个消息希望发出去的时候,它需要将消息封装成一个intent,并发送。这时候,应该是有一个统一的中心(恩,有可能android底层实现的时候不是,但简单这样看是没问题的...)接受到这个消息,并对它进行解析、判定消息类型(这个步骤降低了耦合...),然后检查注册了相匹配的filter或receiver,并创建或唤醒接收者,将消息分发给它。这样做有很多好处。虽然这种传递有的时候不如点对点的传递快(这有些需要速度的地方,我们看到android会通过直接通信来做),但有时候又因为它只经过一跳(姑且这么叫吧...),比复杂的流动又要更快。更重要的是,它耦合性低,在手机平台这种程序组件多变的条件下使用十分适合。并且它可以很容易实现消息的精确或模糊匹配,弹性很大。(我个人曾想在开发一个c++二次平台的时候引入这样的机制,但在c++中,建立一套完整的数据marshal机制不容易,相比之下,用java来做会简单很多...)
恩,废话说了很多,具体讲讲android中intent的使用。当你有一个消息需要传递,如果你明确知道你需要哪个activity或者其他class来响应的话,你可以指定这个类来接受该消息,这被称为显性发送。你需要将intent的class属性设置成目标。这种情况很常见,比如startactivity的时候,会清楚当前activity完了应该是哪个activity,那就明确的发送这个消息。
但是,有的时候你并不确定你的消息是需要具体哪个类来执行,而只是知道接收者该符合哪些条件。比如你只需要有一个接收者能显示用户所选的数据,而不想制定某个具体的方法,这时候你就需要用到隐形发送(传统上,我们可能会考虑用多态,但显然这种方式更为灵活...)。在android中,你可以为intent指定一个action,表示你这个指令需要处理的事情。系统为我们定义了很多action类型,这些类型使系统与我们通信的语言(比如在activity里面加一个main的filter,该activity就会做成该应用的入口点),当然你也可以用于你自己的应用之间的通信(同样当然,也可以自定义...)。强烈建议,在自己程序接收或发出一个系统action的时候,要名副其实。比如你响应一个view动作,做的确实edit的勾当,你发送一个pick消息,其实你想让别人做edit的事,这样都会造成混乱。当然只有action有时候是不够的,在android中我们还可以指定catalog信息和type/data信息,比如所有的显示数据的activity,可能都会响应view action。但很多与我们需要显示的数据类型不一样,可以加一个type信息,明确的指出我们需要显示的数据类型,甚至还可以加上一个catalog信息,指明只有你只有按的是“中键”并发出这样的消息才响应。
从上面可以看出,android的intent可以添加上class, action, data/type, catalog等消息,注册中心会根据这些信息帮你找到符合的接收者。其中class是点对点的指示,一旦指明,其他信息都被忽略。intent中还可以添加key/value的数据,发送方和接收方需要保持统一的key信息和value类型信息,这种数据的marshal在java里做,是不费什么力气的。
android的intent发送,可以分成单播和广播两种。广播的接收者是所有注册了的符合条件的intentreceiver。在单播的情况下,即使有很多符合条件的接收者,也只要有一个出来处理这个消息就好(恩,个人看法,没找到确切条款或抉择的算法,本来想实验一下,没来得及...),这样的情况很容易理解,当你需要修改某个数据的时候,你肯定不会希望有十个编辑器轮流让你来处理。当广播不是这样,一个receiver没有办法阻止其他receiver进行对广播事件的处理。这种情况也很容易理解,比如时钟改变了,闹钟、备忘录等很多程序都需要分别进行处理。在自己的程序的使用中,应该分清楚区别,合理的使用。
9.contentprovider数据模型
数据库操作
从我目前掌握的知识来看,sqlite比较轻量(没有存储过程之类的繁杂手段),用起来也比较简单。实例化一个sqlitedatabase类对象,通过它的apis可以搞定大部分的操作。从sample中看,android中对db的使用有一种比较简单的模式,即派生一个 contentproviderdatabasehelper类来进行sqlitedatabase对象实例的获取工作。基本上, contentproviderdatabasehelper类扮演了一个singleton的角色,提供单一的实例化入口点,并屏蔽了数据库创建、打开升级等细节。在contentprovider中只需要调用contentproviderdatabasehelper的opendatabase方法获取sqlitedatabase的实例就好,而不需要进行数据库状态的判断。
uri
像进行数据库操作需要用sql一样,对contentproivder进行增删改查等操作都是通过一种特定模式的uri来进行的(ig:content: //provider/item/id),uri的能力与url类似,具体细节可以查看sdk。建立自己的contentprovider,只需要派生 contentproivder类并实现insert, delete, update等抽象函数即可。在这些接口中比较特殊的是gettype(uri)。根据传入的uri,该方法按照mime格式返回一个字符串(==!没听过的诡异格式...)唯一标识该uri的类型。所谓uri的类型,就是描述这个uri所进行的操作的种类,比如content://xx/a与 content://xx/a/1不是一个类型(前者是多值操作,后者是单值),但content://xx/a/1和content://xx/a/2 就会是一个类型(只是id号不同而已)。
在contentprovider通常都会实例化一个contenturipraser来辅助解析和操作传入的uri。你需要事先(在static域内)为该contenturipraser建立一个uri的语法树,之后就可以简单调用 contenturipraser类的相关方法进行uri类型判断(match方法),获取加载在uri中的参数等操作。但我看来,这只是在使用上简化了相关操作(不然就需要自己做人肉解析了...),但并没有改变类型判定的模式。你依然需要用switch...case...对uri的类型进行判断,并进行相关后续的操作。从模式来看,这样无疑是具有强烈的坏味道,类似的switch...case...代码要出现n此,每次一个 contentprovider做uri类型的增减都会需要遍历修改每一个switch...case...,当然,如果你使用模式(策略模式...)进行改造对手机程序来说无疑是崩溃似的(类型膨胀,效率降低...),所以,只能是忍一忍了(恩,还好不会扩散到别的类中,维护性上不会有杀人性的麻烦...)。
增删改查
contentprovider 和所有数据源一样,向外提供增删改查操作接口,这些都是基于uri的指令。进行insert操作的时候,你需要传入一个uri和 contentvalues。uri的作用基本就限于指明增减条目的类型(从数据库层面来看就是table名),contentvalues是一个 key/value表的封装,提供方便的api进行插入数据类型和数据值的设置和获取。在数据库层面上来看,这应该是column name与value的对应。但为了屏蔽contentprovider用户涉及到具体数据库的细节,在android的示例中,用了一个小小的模式。它为每一个表建一个基于basecolumn类的派生类(其实完全可以不派生自basecolumn,特别当你的表不基于默认的自动id做主键的时候),这个类通常包括一个描述该表的contenturi对象和形如 public static final title = "title"这样的column到类数据的对应。从改变上角度来看,你可以修改column的名字而不需要更改用户上层代码,增加了灵活性。 insert方法如果成功会返回一个uri,该uri会在原有的uri基础上增加有一个row id。对于为什么使用row id而不是key id我想破了脑袋。到最后,我发现我傻了,因为contentprovider不一定需要使用数据库,使用数据库对应的表也可以没有主键,只有row id,才能在任何底层介质下做索引标识。
但,基于row id在删除和修改操作是会造成一定的混乱。删除和修改操作类似。删除操作需要传入一个uri,一个where字串,一组where的参数(做条件判定...),而修改操作会多一个contentvalues做更新值。着两个操作的uri都支持在末尾添加一个row id。于是混乱就出现了。当在where参数中指明了key id,而在uri中提供了row id,并且row id和key id所指函数不一致的时候,你听谁的?示例代码中的做法是完全无视row id(无语...),如此野蛮的方式我估计也只能在示例中出现,在实际中该如何用,恩,我也不知道。幸运的是,我看了下上层对 contentprovider的删除操作,其实都不会直接进行,而是通过调用cursor的delete方法进行,在这前提下,我想cursor会处理好这些东西吧。
最后一个操作是查询操作,可以想见,查询的参数是最多的,包括uri和一组条件参数。条件参数类型和标准的sql类似,包括 sort, projection 之类的。从这些参数到sql语句的生成,可以寻求querybuilder类的帮助,它提供了一组操作接口,简化了参数到sql的生成工作,哪怕你不懂 sql都完全没有问题(这话说的我自己都觉得有点悬...)。查询返回一个cursor。cursor是一个支持随机读写的指针,不仅如此,它还提供了方便的删除和修改的api,是上层对contentprovider进行操作一个重要对象,需要仔细掌握(cursor还可以绑定到view上,直接送显,并与用户进行交互,真是程序越往上,封装越好,工作越机械没有复杂性了...)。
数据模型
在与界面打交道的cursor、contentresolver等数据操作层中,大量采用观察者模式建立数据层与显示层的联系。一个显示层的视图,可以做成某一种观察者注册到cursor或contentresolver等数据中间层中,在实现底层contentprovider中,我们需要特别注意在对数据进行修改操作(包括增删改...)后,调用相应类型的notify函数,帮助表层对象进行刷新(还有一种刷新方式是从一个view发起的)。可以看到 android的整体数据显示框架有点像mvc的方式。cursor、contentresolver相当于控制层,数据层和显示层的交互通过控制层来掌管,而且控制层很稳定不需要特别定制,通常工作只在定制数据层和显示层空间,还是比较方便和清晰的。
10.学习感想
通过这学期对安卓的学习,大概了解了以上一些知识,对安卓有了初步的了解,这几个月给我的东西我想用有形的和无形的两部分概叙,形的当然就是技术水平的长进,虽然其中肯定有很多的不足,相信慢慢会体会到。