【Android源码 栏目提醒】:网学会员,鉴于大家对Android源码 十分关注,论文会员在此为大家搜集整理了“Android应用程序架构 - 教育”一文,供大家参考学习!
Android应用程序架构src/ java 原代码存放目录gen/ 自动生成目录gen 目录中存放所有由
Android 开发工具自动生成的文件。
目录中最重要的就是 R.java 文件。
这个文件由
Android 开发工具自动产生的。
Android 开发工具会自动根据你放入 res 目录的xml 界面文件、图标与常量,同步更新修改 R.java 文件。
正因为 R.java 文件是由开发工具自动生成的,所以我们应避免手工修改 R.java。
R.java 在应用中起到了字典的作用,它包含了界面、图标、常量等各种资源的 id,通过 R.java,应用可以很方便地找到对应资源。
另外编绎器也会检查 R.java 列表中的资源是否被使用到,没有被使用到的资源不会编绎进软件中,这样可以减少应用在手机占用的空间。
res/ 资源Resource目录在这个目录中我们可以存放应用使用到的各种资源,如 xml 界面文件,图标或常量res/drawable 专门存放图标文件res/layout 专门存放 xml 界面文件,xml 界面文件和 HTML 文件一样,主要用于用户界面显示res/values 专门存放应用使用到的各种常量,作用和 struts 中的国际化资源文件一样。
AndroidManifest.xml 功能清单文件 这个文件列出了应用程序所提供的功能,在这个文件中,你可以指定应用程序使用到的服务如电话服务、互联网服务、短信服务、GPS 服务等等。
另外当你新添加一个 Activity 的时候,也需要在这个文件中进行相应配置,只有配置好后,才能调用此 Activity。
default.properties 系统默认信息,一般是不需要修改此文件LinearLayout 线 性 布 局 、 AbsoluteLayout 绝 对 布 局 、 RelativeLayout 相 对 布 局 、TableLayout表格布局、FrameLayout帧布局数据存储与访问文件使用文件进行数据存储首先给大家介绍使用文件如何对数据进行存储,Activity 提供了 openFileOutput方法可以用于把数据输出到文件中,具体的实现过程与在 J2SE 环境中保存数据到文件中是一样的。
public class FileActivity extends Activity Override public void onCreateBundle savedInstanceState ... FileOutputStream outStream this.openFileOutputquotpeking.txtquotContext.MODE_PRIVATE outStream.writequot北京大学quot.getBytes outStream.close openFileOutput方法的第一参数用于指定文件名称,不能包含路径分隔符“/” ,如果文件不存在,
Android 会自动创建它。
创建的文件保存在/data/data/ltpackage namegt/files 目录,如:/data/data/cn.peking.action/files/peking.txt , 通 过 点 击 Eclipse 菜 单 “Window”-“ShowView”-“Other”,在对话窗口中展开
android 文件夹,选择下面的 File Explorer 视图,然后在File Explorer 视图中展开/data/data/ltpackage namegt/files 目录就可以看到该文件。
openFileOutput 方 法 的 第 二 参 数 用 于 指 定 操 作 模 式 , 有 四 种 模 式 , 分 别 为 :Context.MODE_PRIVATE 0Context.MODE_APPEND 32768Context.MODE_WORLD_READABLE 1Context.MODE_WORLD_WRITEABLE 2Context.MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本高身访问,在该模式下, 写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中。
可以使用 Context.MODE_APPENDContext.MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。
Context.MODE_WORLD_READABLE 和 Context.MODE_WORLD_WRITEABLE 用来控制其他应用是否有权限读写该文件。
MODE_WORLD_READABLE : 表 示 当 前 文 件 可 以 被 其 他 应 用 读 取 ;MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入。
如果希望文件被其他应用读和写,可以传入:openFileOutputquotpeking.txtquot Context.MODE_WORLD_READABLE Context.MODE_WORLD_WRITEABLEandroid 有一套自己的安全模型,当应用程序.apk在安装时系统就会分配给他一个 userid,当该应用要去访问其他资源比如文件的时候,就需要 userid 匹配。
默认情况下,任何应用创建的文件, sharedpreferences, 数据库都应该是私有的 (位于/data/data/ltpackage namegt/files),其 他 程 序 无 法 访 问 。
除 非 在 创 建 时 指 定 了 Context.MODE_WORLD_READABLE 或 者Context.MODE_WORLD_WRITEABLE ,只有这样其他程序才能正确访问。
读取文件内容如果要打开存放在/data/data/ltpackage namegt/files 目录应用私有的文件,可以使用 Activity提供 openFileInput方法。
FileInputStream inStream this.getContext.openFileInputquotpeking.txtquotLog.iquotFileTestquot readInStreaminStreamreadInStream的方法请看本页下面备注。
或者直接使用文件的绝对路径:File file new Filequot/data/data/cn.peking.action/files/peking.txtquotFileInputStream inStream new FileInputStreamfileLog.iquotFileTestquot readInStreaminStream注意:上面文件路径中的“cn.peking.action”为应用所在包,当你在编写代码时应替换为你自己应用使用的包。
对于私有文件只能被创建该文件的应用访问, 如果希望文件能被其他应用读和写,可以在创建 文 件 时 , 指 定 Context.MODE_WORLD_READABLE 和Context.MODE_WORLD_WRITEABLE 权限。
Activity 还提供了 getCacheDir和 getFilesDir方法:getCacheDir方法用于获取/data/data/ltpackage namegt/cache 目录getFilesDir方法用于获取/data/data/ltpackage namegt/files 目录把文件存放在SDCard使用 Activity 的 openFileOutput方法保存文件,文件是存放在手机空间上,一般手机的存储空间不是很大,存放些小文件还行,如果要存放像视频这样的大文件,是不可行的。
对于像视频这样的大文件,我们可以把它存放在 SDCard。
SDCard 是干什么的?你可以把它看作是移动硬盘或 U 盘。
在模拟器中使用 SDCard,你需要先创建一张 SDCard 卡(当然不是真的 SDCard,只是镜像 。
创建 SDCard 可以在 Eclipse 创建模拟器时随同创建,也可以使用 DOS 命令进行创文件)建,如下:在 Dos 窗口中进入
android SDK 安装路径的 tools 目录,输入以下命令创建一张容量为 2G的 SDCard,文件后缀可以随便取,建议使用.img:mksdcard 2048M D:AndroidToolsdcard.img在程序中访问 SDCard,你需要申请访问 SDCard 的权限。
在 AndroidManifest.xml 中加入访问 SDCard 的权限如下:lt-- 在 SDCard 中创建与删除文件权限 --gtltuses-permission
android:namequotandroid.permission.MOUNT_UNMOUNT_FILESYSTEMSquot/gtlt-- 往 SDCard 写入数据权限 --gtltuses-permission
android:namequotandroid.permission.WRITE_EXTERNAL_STORAGEquot/gt要往 SDCard 存放文件,程序必须先判断手机是否装有 SDCard,并且可以进行读写。
注意:访问 SDCard 必须在 AndroidManifest.xml 中加入访问 SDCard 的权限ifEnvironment.getExternalStorageState.equalsEnvironment.MEDIA_MOUNTED File sdCardDir Environment.getExternalStorageDirectory//获取 SDCard 目录 File saveFile new FilesdCardDir “peking.txt”FileOutputStream outStream new FileOutputStreamsaveFileoutStream.writequot北京大学quot.getBytesoutStream.closeEnvironment.getExternalStorageState方法用于获取 SDCard 的状态,如果手机装有 SDCard,并且可以进行读写,那么方法返回的状态等于 Environment.MEDIA_MOUNTED。
Environment.getExternalStorageDirectory方法用于获取 SDCard 的目录, 当然要获取 SDCard的目录,你也可以这样写:File sdCardDir new Filequot/sdcardquot //获取 SDCard 目录File saveFile new FilesdCardDir quotpeking.txtquot//上面两句代码可以合成一句: File saveFile new Filequot/sdcard/peking.txtquotFileOutputStream outStream new FileOutputStreamsaveFileoutStream.writequot北京大学 testquot.getBytesoutStream.close使用SAX或者DOM或者pull读取XML文件在
Android 平台上可以使用 Simple API for XMLSAX 、 Document Object ModelDOM和
Android 附带的 pull 解析器解析 XML 文件。
下面是本例子要解析的 XML 文件:文件名称:peking.xmlltxml versionquot1.0quot encodingquotUTF-8quotgtltpersonsgt ltperson idquot23quotgt ltnamegt李明lt/namegt ltagegt30lt/agegt lt/persongt ltperson idquot20quotgt ltnamegt李向梅lt/namegt ltagegt25lt/agegt lt/persongtlt/personsgt例子定义了一个 javabean 用于存放上面解析出来的 xml 内容, 这个 javabean 为 Person,代码请见本页下面备注:使用SAX读取XML文件SAX 是一个解析速度快并且占用内存少的 xml 解析器,非常适合用于
Android 等移动设备。
SAX 解析 XML 文件采用的是事件驱动,也就是说,它并不需要解析完整个文档,在按内容顺序解析文档的过程中, SAX 会判断当前读到的字符是否合法 XML 语法中的某部分, 如果符合就会触发事件。
所谓事件,其实就是一些回调(callback)方法,这些方法事件定义在ContentHandler 接口。
下面是一些 ContentHandler 接口常用的方法:startDocument当遇到文档的开头的时候,调用这个方法,可以在其中做一些预处理的工作。
endDocument和上面的方法相对应,当文档结束的时候,调用这个方法,可以在其中做一些善后的工作。
startElementString namespaceURI String localName String qName Attributes atts当读到一个开始标签的时候,会触发这个方法。
namespaceURI 就是命名空间,localName是不带命名空间前缀的标签名, qName 是带命名空间前缀的标签名。
通过 atts 可以得到所有的属性名和相应的值。
要注意的是 SAX 中一个重要的特点就是它的流式处理,当遇到一个标签的时候,它并不会纪录下以前所碰到的标签,也就是说,在 startElement方法中,所有你所知道的信息,就是标签的名字和属性,至于标签的嵌套结构,上层标签的名字,是否有子元属等等其它与结构相关的信息, 都是不得而知的,都需要你的程序来完成。
这使得 SAX在编程处理上没有 DOM 来得那么方便。
endElementString uri String localName String name这个方法和上面的方法相对应,在遇到结束标签的时候,调用这个方法。
characterschar ch int start int length这个方法用来处理在 XML 文件中读到的内容,第一个参数用于存放文件的内容,后面两个参数是读到的字符串在这个数组中的起始位置和长度, 使用 new Stringchstartlength就可以获取内容。
只要为 SAX 提供实现 ContentHandler 接口的类,那么该类就可以得到通知事件(实际上就是 SAX 调用了该类中的回调方法) 。
因为 ContentHandler 是一个接口,在使用的时候可能会有些不方便,因此,SAX 还为其制定了一个 Helper 类:DefaultHandler,它实现了这个接口,但是其所有的方法体都为空,在实现的时候,你只需要继承这个类,然后重载相应的方法即可。
使用 SAX 解析 peking.xml 的代码如下:public static ListltPersongt readXMLInputStream inStream try SAXParserFactory spf SAXParserFactory.newInstance SAXParser saxParser spf.newSAXParser //创建解析器 //设置解析器的相关特性,http://xml.org/sax/features/namespaces true 表示开启命名空间特性 saxParser.setPropertyquothttp://xml.org/sax/features/namespacesquottrue XMLContentHandler handler new XMLContentHandler saxParser.parseinStream handler inStream.close return handler.getPersons catch Exception e e.printStackTrace return nullSAX 支持已内置到 JDK1.5 中,你无需添加任何的 jar 文件。
关于 XMLContentHandler 的代码实现请看本页下面备注。
使用DOM读取XML文件除了可以使用 SAX 解析 XML 文件,大家也可以使用熟悉的 DOM 来解析 XML 文件。
DOM解析 XML 文件时,会将 XML 文件的所有内容读取到内存中,然后允许您使用 DOM API遍历 XML 树、检索所需的数据。
使用 DOM 操作 XML 的代码看起来比较直观,并且,在某些方面比基于 SAX 的实现更加简单。
但是,因为 DOM 需要将 XML 文件的所有内容读取到内存中,所以内存的消耗比较大,特别对于运行
Android 的移动设备来说,因为设备的资源比较宝贵,所以建议还是采用 SAX 来解析 XML 文件,当然,如果 XML 文件的内容比较小采用 DOM 是可行的。
使用Pull解析器读取XML文件除了可以使用 SAX 和 DOM 解析 XML 文件,大家也可以使用
Android 内置的 Pull 解析器解析 XML 文件。
Pull 解析器的运行方式与 SAX 解析器相似。
它提供了类似的事件,如:开始元素和结束元素事件,使用 parser.next可以进入下一个元素并触发相应事件。
事件将作为数值代码被发送,因此可以使用一个 switch 对感兴趣的事件进行处理。
当元素开始解析时,调用 parser.nextText方法可以获取下一个 Text 类型元素的值。
使用 Pull 解析器读取 peking.xml 的代码在本页下方备注Pull解析器的
源码及文档下载网址:http://www.xmlpull.org/有些时候,我们需要生成一个 XML 文件,生成 XML 文件的方法有很多,如:可以只使用一个 StringBuilder 组拼 XML 内容, 或者使用 DOM API 生成 XML 然后把内容写入到文件中;文件,或者也可以使用 pull 解析器生成 XML 文件,这里推荐大家使用 Pull 解析器。
使用 Pull 解析器生成一个与 peking.xml 文件内容相同的 mypeking.xml 文件,代码在本页下方备注使用代码如下(生成 XML 文件) :File xmlFile new Filequotmypeking.xmlquotFileOutputStream outStream new FileOutputStreamxmlFileOutputStreamWriter outStreamWriter new OutputStreamWriteroutStream quotUTF-8quotBufferedWriter writer new BufferedWriteroutStreamWriterwriteXMLpersons writerwriter.flushwriter.close如果只想得到生成的 xml 内容,可以使用 StringWriter:StringWriter writer new StringWriterwriteXMLpersons writerString content writer.toStringSharedPreferences使用SharedPreferences进行数据存储很多时候我们开发的软件需要向用户提供软件参数设置功能,例如我们常用的 QQ,用户可以设置是否允许陌生人添加自己为好友。
对于软件配置参数的保存,如果是 window 软件通常我们会采用 ini 文件进行保存,如果是 j2se 应用,我们会采用 properties 属性文件进行保存。
如果是
Android 应用,我们最适合采用什么方式保存软件配置参数呢?
Android 平台给我们提供了一个 SharedPreferences 类,它是一个轻量级的存储类,特别适合用于保存软件配置参数。
使用 SharedPreferences 保存数据,其背后是用 xml 文件存放数据,文件存放在/data/data/ltpackage namegt/shared_prefs 目录下:SharedPreferences sharedPreferences getSharedPreferencesquotpekingquotContext.MODE_PRIVATEEditor editor sharedPreferences.edit//获取编辑器editor.putStringquotnamequot quot北京大学quoteditor.putIntquotagequot 4editor.commit//提交修改生成的 peking.xml 文件内容如下:ltxml version1.0 encodingutf-8 standaloneyes gtltmapgtltstring namequotnamequotgt北京大学lt/stringgtltint namequotagequot valuequot4quot /gtlt/mapgt因为 SharedPreferences 背后是使用 xml 文件保存数据, getSharedPreferencesnamemode方法的第一个参数用于指定该文件的名称,名称不用带后缀,后缀会由
Android 自动加上。
方法的第二个参数指定文件的操作模式, 共有四种操作模式, 这四种模式前面介绍使用文件方式保存数据时已经讲解过。
如果希望 SharedPreferences 背后使用的 xml 文件能被其他应用读和写 , 可 以 指 定 Context.MODE_WORLD_READABLE 和Context.MODE_WORLD_WRITEABLE 权限。
另外 Activity 还提供了另一个 getPreferencesmode方法操作 SharedPreferences,这个方法默认使用当前类不带包名的类名作为文件的名称。
访问SharedPreferences中的数据访问 SharedPreferences 中的数据代码如下:SharedPreferences sharedPreferences getSharedPreferencesquotpekingquotContext.MODE_PRIVATE//getString第二个参数为缺省值,如果 preference 中不存在该 key,将返回缺省值String name sharedPreferences.getStringquotnamequot quotquotint age sharedPreferences.getIntquotagequot 1如 果 访 问 其 他 应 用 中 的 Preference , 前 提 条 件 是 : 该 preference 创 建 时 指 定 了Context.MODE_WORLD_READABLE 或者 Context.MODE_WORLD_WRITEABLE 权限。
如:有个ltpackage namegt为 cn.peking.action 的应用使用下面语句创建了 preference。
getSharedPreferencesquotpekingquot Context.MODE_WORLD_READABLE其他应用要访问上面应用的 preference, 首先需要创建上面应用的 Context, 然后通过 Context访问 preference , 访问 preference 时会在应用所在包下的 shared_prefs 目录找到 preference :Context otherAppsContext createPackageContextquotcn.peking.actionquotContext.CONTEXT_IGNORE_SECURITYSharedPreferences sharedPreferences otherAppsContext.getSharedPreferencesquotpekingquotContext.MODE_WORLD_READABLEString name sharedPreferences.getStringquotnamequot quotquotint age sharedPreferences.getIntquotagequot 0如果不通过创建 Context 访问其他应用的 preference,可以以读取 xml 文件方式直接访问其他应用 preference 对应的 xml 文件,如:File xmlFile new File“/data/data/ltpackage namegt/shared_prefs/peking.xml”//ltpackagenamegt应替换成应用的包名SQLite数据库使用嵌入式关系型SQLite数据库存储数据除了可以使用文件或 SharedPreferences 存储数据, 还可以选择使用 SQLite 数据库存储数据。
在
Android 平台上,集成了一个嵌入式关系型数据库—SQLite,SQLite3 支持 NULL、INTEGER、REAL(浮点数字) 、TEXT字符串文本和 BLOB二进制对象数据类型,虽然它支持的类型虽然只有五种,但实际上 sqlite3 也接受 varcharn、charn、decimalps 等数据类型,只不过在运算或保存时会转成对应的五种数据类型。
SQLite 最大的特点是你可以保存任何类型的数据到任何字段中,无论这列声明的数据类型是什么。
例如:可以在 Integer字段中存放字符串,或者在布尔型字段中存放浮点数,或者在字符型字段中存放日期型值。
但有一种情况例外:定义为 INTEGER PRIMARY KEY 的字段只能存储 64 位整数, 当向这种字段中保存除整数以外的数据时, 将会产生错误。
另外, SQLite 在解析 CREATE TABLE语句时,会忽略 CREATE TABLE 语句中跟在字段名后面的数据类型信息,如下面语句会忽略 name 字段的类型信息:CREATE TABLE person personid integer primary key autoincrement name varchar20SQLite 可以解析大部分标准 SQL 语句,如:查询语句:select from 表名 where 条件子句 group by 分组字句 having ... order by 排序子句如:select from person select from person order by id desc select name from person group by name having countgt1分页 SQL 与 mysql 类似,下面 SQL 语句获取 5 条记录,跳过前面 3 条记录select from Account limit 5 offset 3 或者 select from Account limit 35插入语句:insert into 表名字段列表 values值列表。
如: insert into personname agevalues‘北大’3更新语句:update 表名 set 字段名值 where 条件子句。
如:update person set name‘北大‘ where id10删除语句:delete from 表名 where 条件子句。
如:delete from person where id10使用SQLiteDatabase操作SQLite数据库
Android 提供了一个名为 SQLiteDatabase 的类,该类封装了一些操作数据库的 API,使用该类可以完成对数据进行添加Create、查询Retrieve、更新Update.
上一篇:
Android应用程序内部启动Activity过程(startActivity)的源代码分析
下一篇:
一个人晕着也能去看病打针