我们将按照SDK文档的组织思路,探索Android的Statusbar应用的开发,本文适合已经完成新兵训练课的同学,你至少浏览过该课程内容。
实现Android的UI
本节内容有
a、怎么实现一个屏幕UI;
b、如何在xml文件中定义屏幕UI并载入到程序代码中;
c、响应UI的各种处理。
Topic1 屏幕元素的层次
Android应用的基本功能单元是Activity,但它本身不具备在屏幕显示的能力;
Android平台的基本UI表达单元是view和viewgroup,前者抽象了widget,后者抽象了layout.
用View和Viewgroup的节点树来定义Activity的UI,构建时可使用平台预定义或自己扩充的widget和layout。把树的根节点传给Activity的setContentView()函数,Android系统就保存根节点的引用,当该Activity被激活并接收焦点时,系统通知该Activity并通知它的根节点计算并显示整棵树,由根节点依次通知它的各子节点重画,Viewgroup子节点负责其直接儿子的重画。
每个Viewgroup类都嵌套实现一个派生自ViewGroup.LayoutParams类,供其子view描述大小和位置,每个子view必须定义与其父viewgroup相近的LayoutParams。viewgroup包含宽度和高度,还可以含页边距和边框。
演示:
a、开启emulator,用hierarchyviewer工具查看status bar的view/viewgroup树。
b、查看源代码,找到向系统设置该树根节点的地方。
Topic2 常用Layout对象(viewgroup)
最简单的就是FrameLayout, 在屏幕上预留出一块区域,此后每次添加对象(如图片)时,都直接从左上角开始,如果填入的对象不是透明的,该区域先前的对象直接被抹掉。
只简单水平或垂直排列所有子view的LinearLayout,不论子view宽度/高度,都独自占一行(vertical)或列(horizontal)。各子view可指定间距及对齐方式,还可以用weight来指定空白空间的分配比例。
表格布局TableLayout可以在每个单元里设定一个view对象。
绝对布局AbsoluteLayout允许子view指定自己在屏幕上的绝对坐标,除非迫不得已,不推荐使用。
相对布局RelativeLayout则允许子view指定相对于其它子view的相对位置。
这里用一张表简单总结了重要的viewgroup(包含这里没列出来的)。
演示:Statusbar用到的viewgroup。
Topic3 带数据的viewgroup
带UI的viewgroup对象通常派生AdapterView(如Gallery和ListView),这些对象需要
a、在layout里填数据。绑定到某个负责获取数据(hard code或从db中查询)的Adapter即可。
b、处理用户的选择。在AdapterView.OnItemClickerListener类的成员onItemClick方法监听。
演示:Statusbar没有此类view group.
Topic4 在XML中设计屏幕
Android的各个派生View类成员的XML语法在Layout Resources里有定义。在应用的目录res/layout下每个XML文件描述一个View(简单的可视元素或含有子对象的layout元素),最后分别被编译成一个单独View资源,在Activity.onCreate()中可通过setContentView(R.layout.xxx_file_name)加载到代码中。
演示:查看并分析Statusbar屏幕对应的XML文件。
演示:向statusbar中新增一个icon(right icon/类似digital clock)。
Topic5 处理屏幕元素
通过Activity.findViewById方法可以得到屏幕元素,然后使用它可用的方法。
演示:Statusbar屏幕元素的处理。
Topic6 监听UI通知
除Android系统自动发出调用的一些UI通知(如Activity中键盘按下与松开,Widget的焦点切换)外,其它回调都需要手工注册(如按钮的点击事件)。
演示:Statusbar手工注册的回调。
Topic7 应用程序的Theme
a、在XML中分别指定application级或activity级的theme属性。
b、在创建view之前由代码设置,不推荐使用这种方法,因为代码设置的theme不能改变在应用启动前的运行系统动画的theme。
Topic8 UI元素及概念的术语表
#Activity
Android应用程序的标准屏,一个可以被本应用或其它应用抛出的匹配Intent启动的类。是一个全屏、浮动或透明窗口的可见化表示,并接收处理UI事件,进而完成复杂的Task.
#View
屏幕一个矩形区,绘画、处理触屏点击,按键及其它交互事件。它是Activity或Dialog屏(text boxes, windows等)组件的基类。接收来自容纳它的容器对象调用进行自绘,并把自己理想的位置和大小告诉它的父对象(尽管父对象可以不理会)
#View Group
可持有多个子View对象的容器,决定了这些子对象的位置与总的大小,需要的时候通知它们进行自绘。可以是不可见的layout本身,也可以自带UI(如滚动列表框)。在widget包中。
#Widget
可自绘并处理UI事件的元素,如文本框或弹出菜单。
#Drawable
装到其它UI元素中的可视元素,常用作背景图。不接收事件,但具备其它属性如状态及定时启用是派生的动画对象或图片库所需的功能。
#Panel
只是一个概念,一个与父窗体紧密联系的View能处理点击并进行简单的跟它父窗体相关的功能。它会浮动在父窗体前并相对于父窗体定位(如Android自带的option菜单可为各屏共用),目前没有类或方法用来创建Panel
#Dialog
浮动窗体,可含有按钮,轻量级窗体常用于处理简单事件(如按钮按下)或者返回结果。不会保存在历史栈里,不适合含有复杂的layout或作复杂的处理,自带有一些常用的标准布局。
#Window
描述通用窗体的常见抽象,如外观(标题栏文本,菜单的定位及内容等)。Dialog和Activity用它的某个实现来绘制窗体。一般不需要实现此类。
#Surface
用来合成屏幕的一块内存,持有用于绘画的Canvas对象,提供绘制layers和改变大小用的辅助方法,不要直接使用此类,可用SurfaceView.
#SurfaceView
一个封装Surface类的View对象用来绘图,提供一些可动态指定它大小和格式的方法。摄像程序的预览功能就用它来实现。为资源紧张型应用(如游戏)提供了一种独立于UI线程进行绘图的方式,会使用额外的内存,同时支持Canvas和OpenGL ES图形。
#Canvas
绘制surface实际位合成,提供绘画bitmaps,线,圆,矩形,文本等方法,是在屏幕画2D对象最简单的方式。便不支持硬件加速。
#OpenGL ES
用于快速、复杂的3D图像,比Canvas对象难用,但更适于3D对象。功能分布在opengl和javax.microedition.khronos.opengles两个包里。
演示:Statusbar涉及到的术语
Android的组件
本节详细描绘各个关键组件(Intents, Activities, Views和事件)。Android应用更像松耦合的组件联邦而不是一个紧耦合的应用,默认各组件都跑在同一进程里,也可以指定某组件在一个单独的进程中运行。
AndroidManifest.xml
Activities
Views
Intents
Services
Notifications
#Android强烈推荐的通知用户注意的机制,在状态栏上显示一个小图标,用户与该图标交互来接收信息。
ContentProviders
演示:Statusbar的各组件.
存储/读取数据
Android应用读写数据有多种方式,各针对不同的需要。
Preferences
Files
Databases
Content Providers
Network
演示:Statusbar用到数据读写功能吗?
安全模型
权限控制与请求,让应用间共享与安全同时兼顾。
演示:Statusbar安全相关?
资源管理与i18n
资源管理系统,资源(如图片,本地化字符串,XML布局)是属于应用的,在运行时解析。本节包括:
a、如何国际化与本地化。
b、如何解析、装载需要的资源。
c、如何创建与使用资源。
演示:Statusbar的资源。
2008年12月30日星期二
2008年12月21日星期日
Android应用开发之新兵训练课
Android为上层就用程序开发提供了SDK及其文档,这是一个除了源代碼之外的官方的正式信息来源,所有从事就用开发的新兵蛋蛋都可以从这里开始,当然,就像玩游戏一样,如果你没有耐心慢慢来(有时候也确实挺无聊的),完全可以到网上去搜一下各种各样的秘笈。
思绪是不是回到了那快乐却一去不复返了的青春年华?快回来吧,抓紧热身,我们需要按文档指导去安装开发环境(SDK,eclipse及ADT),了解开发和调试的基本知识,然后照猫画虎,整个"Hello Android"玩玩。
我在看各种文档是常常会不停地打开各个相关的链接,想一下子把什么都搞明白。到最后往往都会忘记自己本来是想干什么来着。所以现在我有必要让思想做一些改变,不是什么都需要现在就搞清楚的,要会舍得。要好读文档,要不求甚解。
是时候了解Android应用程序作个简单地系統剖析了,只要对各个組成块有个简单概念就可以了(Activity, Broadcast Intent Receiver, Service和Content Provider),技能是练出来的,没听说过可以看出来的(当然不是说不需要看,而是说看到的要转化成技能,最終还得练),就让我们练习的过程中时不时再回过头来看看吧。
看一下Android就用开发的新手上路都要做些什么吧。闯关去吧,如果你太菜,你也可以选择看每关现存的攻略,但是建议多点耐心,最好别上来就看攻略,至少应该给自己一个说得过去的理由:我不是个孬种,我心安理得。
新兵同志,你的第一项任务是赶到演练场,找到被敌人摧毁的信息系統,尽快修复它的Notepadv1部分,使之正常工作,让我们的人能够向系統添加信息到数据库中,修改信息的功能对我们来说并不是件紧迫的任务。如果我们的情报没错的话,在你到达演练场的时候,要修复的系統还没有完全被摧毁,这将大大节省你的修复时间。这是你唯一可以找到帮助的地方,你现在开始直到任务完成,你将需要独自行动,再见。
很好,我们又有新任务了,我们刚刚接到指示需要立刻完成往信息系统添加记录,编辑和删除已有记录的功能。这一次没有提供新的帮助信息。你完成任务后,呆在原地等待命令。
你的成绩很不错,接下来是整个新兵训练的最后一关:我们正在用的系统似乎不能很好的维护自己的状态。新的任务要求:
a、新建/编辑信息界面直接与数据库交互取得信息记录,外部调用只告知记录号。
b、该界面的确认按钮被按下时,主动结束本活动。
c、新建/编辑活动结束时,保存当前信息记录号,它会在下次构建此活动界面实例时由系统传入。
d、利用系统机制,在新建/编辑活动主动或被动暂停时,保存当前信息到数据库里,新建的信息还需要维护新生成的记录号以便暂停的活动恢复里可以继续编辑。
e、新建/编辑活动恢复时,用实际数据库内容更新界面。
恭喜!新兵训练课结束。回去自己写个心得/体会,总结一下。
思绪是不是回到了那快乐却一去不复返了的青春年华?快回来吧,抓紧热身,我们需要按文档指导去安装开发环境(SDK,eclipse及ADT),了解开发和调试的基本知识,然后照猫画虎,整个"Hello Android"玩玩。
我在看各种文档是常常会不停地打开各个相关的链接,想一下子把什么都搞明白。到最后往往都会忘记自己本来是想干什么来着。所以现在我有必要让思想做一些改变,不是什么都需要现在就搞清楚的,要会舍得。要好读文档,要不求甚解。
是时候了解Android应用程序作个简单地系統剖析了,只要对各个組成块有个简单概念就可以了(Activity, Broadcast Intent Receiver, Service和Content Provider),技能是练出来的,没听说过可以看出来的(当然不是说不需要看,而是说看到的要转化成技能,最終还得练),就让我们练习的过程中时不时再回过头来看看吧。
看一下Android就用开发的新手上路都要做些什么吧。闯关去吧,如果你太菜,你也可以选择看每关现存的攻略,但是建议多点耐心,最好别上来就看攻略,至少应该给自己一个说得过去的理由:我不是个孬种,我心安理得。
新兵同志,你的第一项任务是赶到演练场,找到被敌人摧毁的信息系統,尽快修复它的Notepadv1部分,使之正常工作,让我们的人能够向系統添加信息到数据库中,修改信息的功能对我们来说并不是件紧迫的任务。如果我们的情报没错的话,在你到达演练场的时候,要修复的系統还没有完全被摧毁,这将大大节省你的修复时间。这是你唯一可以找到帮助的地方,你现在开始直到任务完成,你将需要独自行动,再见。
很好,我们又有新任务了,我们刚刚接到指示需要立刻完成往信息系统添加记录,编辑和删除已有记录的功能。这一次没有提供新的帮助信息。你完成任务后,呆在原地等待命令。
你的成绩很不错,接下来是整个新兵训练的最后一关:我们正在用的系统似乎不能很好的维护自己的状态。新的任务要求:
a、新建/编辑信息界面直接与数据库交互取得信息记录,外部调用只告知记录号。
b、该界面的确认按钮被按下时,主动结束本活动。
c、新建/编辑活动结束时,保存当前信息记录号,它会在下次构建此活动界面实例时由系统传入。
d、利用系统机制,在新建/编辑活动主动或被动暂停时,保存当前信息到数据库里,新建的信息还需要维护新生成的记录号以便暂停的活动恢复里可以继续编辑。
e、新建/编辑活动恢复时,用实际数据库内容更新界面。
恭喜!新兵训练课结束。回去自己写个心得/体会,总结一下。
2008年12月20日星期六
Linux启动过程性能分析工具Bootchar的工作原理
它在linux启动过程收集信息并保存在内存中,到启动完成后才把这引起信息保存到磁盘。它統計CPU和磁盘使用状态,进程信息,数据来源于/proc文件系統。
通过修改bootloader初始化选项并设定为bootchartd的路径(init=/sbin/bootchartd),它就会被bootloader启动,它初始化完成后转调linux的内核,这样它就可以监管linux的整个启动过程。
这样的思路同样可以在嵌入式linux系統中使用,先要移植bootchart使它可以在目标平台上运行,然后修改目标平台的bootloader,让bootloader启动bootchartd而不是linux内核,工具的关键在于从/proc文件系統。
通过修改bootloader初始化选项并设定为bootchartd的路径(init=/sbin/bootchartd),它就会被bootloader启动,它初始化完成后转调linux的内核,这样它就可以监管linux的整个启动过程。
这样的思路同样可以在嵌入式linux系統中使用,先要移植bootchart使它可以在目标平台上运行,然后修改目标平台的bootloader,让bootloader启动bootchartd而不是linux内核,工具的关键在于从/proc文件系統。
Ubuntu Tips
Linux有发布版本有不少,曾经尝试过一些,现在因为工作的原因,开始用了ubuntu,在联网的环境里ubuntu是一个相当不错的选择,这个社区比较活跃,当然,因为活跃,所以不是很多东西都很成熟。
我们常常都会觉得我们系統启动时间太长,恨不能一按power键,系統就ON了,当然,那不过是a pleasant dream, 据说有一个叫做bootchart的項目,安装后重启系統,就可以收集启动信息,以图表的形式保存在/var/log/bootchart/,想不想试一下?
在大陸,网络状况常常是相当的不理想,所以安装完Ubuntu 8.10后,我第一件事就是要修改/etc/apt/sources.list,用大家公认的台湾官方链接取代默认的設置,此后,运行apt-get系列的命令要快很多很多,光从这一点看,我们拿什么来“和平統一”台湾啊?
各位看官,听还听收音机吗?听音乐吗?我现在喜欢在Linux上边玩边听网络收音机,rhythmbox很不错的,加拿大的CBC基本上总是可以听到的。
Ubuntu8.10发布的安装盘分两种,desktop版和server版,二者是有点区别的,最明显的就是前者不包含各种服务如www,ftp,mail,ssh,telnet等服务,后者不包含图形化的桌面系統如KDE和gnome。但是Linux有一个好处,就是你的地盘你做主,缺什么完全可以自己补装就可以了,我以前在server加装过gnome,后来直接装了desktop版,今天需要手工加装telnet和openssh-server后就可以从另一台机器远程登录了,sudo apt-get install xinetd telnetd openssh-server。
我们常常都会觉得我们系統启动时间太长,恨不能一按power键,系統就ON了,当然,那不过是a pleasant dream, 据说有一个叫做bootchart的項目,安装后重启系統,就可以收集启动信息,以图表的形式保存在/var/log/bootchart/,想不想试一下?
在大陸,网络状况常常是相当的不理想,所以安装完Ubuntu 8.10后,我第一件事就是要修改/etc/apt/sources.list,用大家公认的台湾官方链接取代默认的設置,此后,运行apt-get系列的命令要快很多很多,光从这一点看,我们拿什么来“和平統一”台湾啊?
各位看官,听还听收音机吗?听音乐吗?我现在喜欢在Linux上边玩边听网络收音机,rhythmbox很不错的,加拿大的CBC基本上总是可以听到的。
Ubuntu8.10发布的安装盘分两种,desktop版和server版,二者是有点区别的,最明显的就是前者不包含各种服务如www,ftp,mail,ssh,telnet等服务,后者不包含图形化的桌面系統如KDE和gnome。但是Linux有一个好处,就是你的地盘你做主,缺什么完全可以自己补装就可以了,我以前在server加装过gnome,后来直接装了desktop版,今天需要手工加装telnet和openssh-server后就可以从另一台机器远程登录了,sudo apt-get install xinetd telnetd openssh-server。
订阅:
评论 (Atom)