【Android源码 栏目提醒】:本文主要为网学会员提供“Android应用程序开发以及背后的设计思想深度剖析(1) - 企业软件开发”,希望对需要Android应用程序开发以及背后的设计思想深度剖析(1) - 企业软件开发网友有所帮助,学习一下!
Android应用程序开发以及背后的设计思想深度剖析1 本文内容主题是透过应用程序来分析
Android系统的设计原理与构架。
我们先会简单介绍一下
Android里的应用程序编程然后以这些应用程序在运行环境上的需求来分析出为什么我们的
Android系统需要今天这样的设计方案这样的设计会有怎样的意义
Android究竟是基于怎样的考虑才变成今天的这个样子所以本文更多的分析
Android应用程序设计背后的思想品味良好架构设计的魅力。
分五次连载完成第一部分是最简单的部分解析
Android应用程序的开发流程。
特别声明本系列文章LiAnLab.org著作权所有转载请注明出处。
作者系LiAnLab.org资深
Android技术顾问吴赫老师。
本系列文章交流与讨论:宋宝华Barry 1.
Android应用程序 在目前
Android大红大紫的情况下很多人对编写
Android应用程序已经有了足够深入的了解。
即便是没有充分的认识在现在
Android手机已经相当普及的情况下大家至少也会知道
Android的应用程序会是一个以.apk为后缀名的文件在Windows系统里还会是一个带可爱机器人图标的文件。
那这个apk包又有什么样的含义呢 如果您正在使用Linux操作系统可以使用命令file命令来查看这一文件的类型。
比如我们下载了一个Sample.apk的文件则使用下面的命令 file Sample.apk Sample.apk: Zip archive data at least v1.0 to extract 对没有看错只一个简单的zip文件。
要是做过Java开发的人可以对这种格式很亲切因为传说中的.jar、.war格式都是Zip压缩格式的文件。
我们可继续使用unzip命令将这一文件解压或是任何的解压工具zip是人类历史是最会古老最为普及的压缩格式之一几乎所有压缩工具都支持。
通过解压我们就得到了下面的文件内容 AndroidManifest.xml classes.dex resources.arsc META-INF res 到这里我们就可以看到一个
Android应用程序结构其实是异常简单的。
这五部分内容其中META-INF和res是目录其他是文件除了META-INF是这一.apk文件的校验信息resources.arsc是资源的索引文件其他三部分则构成了
Android应用程序的全部。
?? AndroidManifest.xml这是每个
Android应用程序包的配置文件这里会保存应用程序名字、作者、所实现的功能、以及一些权限验证信息。
但很可惜在编译完成的.apk文件里这些文件都被编译成了二进制版本我们暂时没有办法看到内容后面我们可以再看看具体的内容。
?? classes.dex这则是
Android应用程序实现的逻辑部分也就是通过Java编程写出来而被编译过的代码。
这种特殊的格式是
Android里特定可执行格式是可由Dalvik虚拟机所执行的代码这部分内容我们也会在后续的介绍Dalvik虚拟机的章节里介绍。
?? res这一目录里则保存了
Android所有图形界面设计相关的内容比如界面应该长成什么样子、支持哪些语言显示等等。
从一个
android应用程序的包文件内容我们可以看到
android应用程序的特点这也是
Android编程上的一些特征 1 简单最终生成的结果是如些简单的三种组成则他们的编程上也不会有太大的困难性。
这并不是说
Android系统里无法实现很复杂的应用程序事实上
Android系统拥有世界上仅次于iOS的应用程序生态环境也拥有复杂的办公软件、大型3D游戏。
而只是说如果要实现和构成同样的逻辑它必然会拥有其他格式混杂的系统更简化的编程模式。
2 Java操作系统既然我们编译得到的结果classes.dex文件是用于Java虚拟机虽然是Dalvik虚拟机但实际上这一虚拟机只是一种特定的Java解析器和虚拟机执行环境 解析执行的于是我们也可以猜想到我们的
Android系统必然是一个Java操作系统。
我们在后面会解释如果把
Android系统直接看成Linux内核和Java语言组合到一起的操作系统很不准确但事实上
Android也还是Java操作系统Java是唯一的系统入口。
使用MVC设计模式所谓的MVC就是ModelViewController的首字母组合起来的一种设计模式主要思想就是把显示与逻辑实现分离。
Model用于保存上下文状态、View用于显示、而Controller则是用于处理用户交互。
三者之间有着如下图所示的交互模型交互只到Controller而显示更新只通过View进行这两者再与Model交换界面状态信息 在现代的图形交互相关的设计里MVC几乎是在图形交互处理上的不二选择这样系统设计包括一些J2EE的应用服务器框架最受欢迎的Firefox浏览器iOSMacOSX等等。
这些使用MVC模式的最显著特点就是显示与逻辑分离在
Android应用程序里我们看到了用于逻辑实现的classes.dex也看到用于显示的res于是我们也可以猜想到在UI上便肯定会使用MVC设计模式。
当然所谓的
Android应用程序编程不会只有这些内容。
到目前为止我们也只是分析.apk文件于是我们可以回过头来看看
Android应用被编译出来的过程。
2.
Android编程 从编程角度来说
Android应用程序编程几乎只与Java相关而Java平台本身是出了名跨平台利器理论上来说所有Java环境里使用的编程工具、IDE工具皆可用于
Android的编程。
Android SDK环境里提供的编程工具是基于标准的Java编译工具ant的但事实上一些大型的
Android软件工程更倾向于使用Maven这样的并行化编译工具maven.apache.org。
如果以前有过Java编程经验会知道Java环境里的图形化IDEIntegrated Development Environment工具并非只有Eclipse一种实际上Java的官方IDE是NetBeans而商用化的Java大型项目开发者也可能会比较钟意于使用IntelliJ而从底层开发角度来说可能使用vim是更合适的选择可以灵活地在C/C与Java代码之间进行切换。
总而言之几乎所有的Java环境的编程工具都可以用于
Android编程。
对于这些工具呢熟悉工具的使用是件好事所谓“磨刀不误砍柴工”为将来提升效率这是件好事。
但是要磨刀过多柴没砍着转型成“磨刀工”了。
如果过多地在这些编程工具上纠结尝试反而忽视了所编代码的本身这倒会舍本逐末。
我们既然是研究
Android编程这时仅说明两种
Android官方提供的编程方法使用
Android SDK工具包编程或是使用Eclipse ADT插件编程。
2.1 使用
Android SDK工具包 在
Android开发过程中如果Eclipse环境不可得的情况下可以直接使用SDK来创建应用程序工程。
首先需要安装某一个版本的
Android SDK开发包这个工具包可以到http://developer.
android.com/sdk/index.html这个网址去下载根据开发所用的主机是Windows、Linux还是MacOS XMacOS仅支持Intel芯片不支持之前的PowerPC芯片下载对应的.zip文件比如
android-sdk_r19-linux.zip。
下载完成后解压到一个固定的目录我们这里假定是通过环境变量
ANDROID_SDK_PATH指定的目录。
下载的SDK包默认是没有
Android开发环境支持的需要通过tools目录里的一个
android工具来下载相应的SDK版本以用于开发。
我们通过运行
ANDROID_SDK_PATH/tools/
android会得到如下的界面 在上面的安装界面里选择不同的开发工具包其中Tools里包含一些开发用的工具如我们的SDK包实际上也会在这一界面里进行更新。
而对于不同的
Android版本1.5到4.1我们必须选择下载某个SDK版本来进行开发。
而下载完之后的版本信息我们既可以在这一图形界面里看到也可以通过命令行来查看。
ANDROID_SDK_PATH/tools/
android list targets id: 1 or quotandroid-16quot Name:
Android 4.1 Type: Platform API level: 16 Revision: 1 Skins: HVGA QVGA WQVGA400 WQVGA432 WSVGA WVGA800 default WVGA854 WXGA720 WXGA800 WXGA800-7in ABIs : armeabi-v7a ---------- id: 2 or quotGoogle Inc.:Google APIs:16quot Name: Google APIs Type: Add-On Vendor: Google Inc. Revision: 1 Description:
Android Google APIs Based on
Android 4.1 API level 16 Libraries: com.google.
android.media.effects effects.jar Collection of video effects com.
android.future.usb.accessory usb.jar API for USB Accessories com.google.
android.maps maps.jar API for Google Maps Skins: WVGA854 WQVGA400 WSVGA WXGA800-7in WXGA720 HVGA WQVGA432 WVGA800 default QVGA WXGA800 ABIs : armeabi-v7a 通过
android list targets列出来的信息可以用于后续的开发之用比如对于不同的target最后得到了id:1、id:2这样的信息则可以被用于应用程序工程的创建。
而细心一点的读者会看到同一个4.1版本的SDK实际可分为”
android-16”和quotGoogle Inc.:Google APIs:16quot这样的分界也还有有意义的”
android-16”用于“纯”的
android 4.1版的应用程序开发而“Google Inc.:Google APIs:16”则加入了Google的开发包。
配置好环境之后如果我们需要创建
Android应用程序。
tools/
android这个工具同时也具备可以创建
Android应用程序工程的能力。
我们输入
ANDROID_SDK_PATH/tools/
android create project -n Hello -t 1 -k org.lianlab.hello -a Helloworld -p hello 这样我们就在hello目录里创建了一个
Android的应用程序名字是Hello使用API16
Android 4.1的API版本包名是org.lianlab.hello而默认会被执行到的Activity会是叫Helloworld的Activity类。
掌握
Android工具的一些使用方法也是有意义的比如当我们的Eclipse工程被破坏的情况下我们依然可以手工修复这一
Android应用程序工程。
或是需要修改该工程的API版本的话可以使用下面的命令
ANDROID_SDK_PATH/tools/
android updateproject -t 2 -p . 在这个工程里如果我们不加任何修改会生成一个应用程序这个应用程序运行的效果是生成一个黑色的图形界面打印出一行quotHello World Helloworldquot。
如果我们需要对这一工程进行编译等操作的话剩下的事情就属于标准的Java编译了标准的Java编译使用的是antant.apache.org编译工具。
我们先改变当前目录到hello然后就可以通过” ant –projecthelp”来查看可以被执行的
Android编译工程 ant -projecthelp Buildfile: /Users/wuhe/
android/workspace/NotePad/bin/tmp/hello/build.xml Main targets: clean Removes output files created by other targets. debug Builds the application and signs it with a debug key. install Installs the newly build package. Must be used in conjunction with a build target debug/release/instrument. If the application was previously installed the application is reinstalled if the signature matches. installd Installs only the debug package. installi Installs only the instrumented package. installr Installs only the release package. installt Installs only the test and tested packages. instrument Builds an instrumented packaged. release Builds the application in release mode. test Runs tests from the package defined in test.package property uninstall Uninstalls the application from a running emulator or device. Default target: help 但如果只是编译我们可以使用antdebug生成Debug的.apk文件这时生成的文件会被放到bin/Hello-debug.apk。
此时生成的Hello-debug.apk已经直接可以安装到
Android设备上进行测试运行。
我们也可以使用ant release来生成一个bin/Hello-release-unsigned.apk而这时的.apk文件则需要通过jarsigner对文件进行验证才能进行安装。
通过antdebug这一编译脚本我们可以看到详细的编译过程。
我们可以看到一个
Android的工程最后会是通过如图所示的方式生成最后的.apk文件。
把一个
Android的源代码工程编译成.apk的
Android应用程序其过程如下 1 所有的资源文件都会被aapt进行处理。
所有的XML文件都会被aapt解析成二进制格式准确地说这样的二进制格式是可以被直接映射到内存里的二进制树。
做过XML相关开发的工程师都会知道XML的验证与解析是非常消耗时间与内存的而通过编译时进行XML解析则节省了运行时的开销。
当然解析的结果最后会被aapt通过一个R.java保存一个二进制树的索引编程时可通过这个R.java文件进行XML的访问。
aapt会处理所有的资源文件也就是Java代码之外的任何静态性文件这样处理既保证了资源文件间的互相索引得到了验证也确保了R.java可以索引到这个应用程序里所有的资源。
2 所有的Java文件都会被JDK里的javac工具编译成bin目录下按源代码包结构组织的.class文件.class是标准的Java可解析执行的格式比如我们这个例子里生成的bin/classes/org/lianlab/hello/.class文件。
然后这些文件会通过SDK里提供的一个dx工具转换成classes.dex文件。
这一文件就是会被Dalvik虚拟机所解析执行的 3 最后我们得到的编译过的二进制资源文件和classes.dex可执行文件会通过一个apkbuilder工具通过zip压缩算法打包到一个文件里生成了我们所常见的.apk文件。
4 最后.apk文件会通过jarsigner工具进行校验这一校验值会需要一个数字签名。
如果我们申请了
Android开发者帐号这一数字签名就是
Android所分发的那个数字证书如果没有我们则使用debug模式使用本地生成的一个随机的数字证书这一文件位于/.
android/debug.keystore。
虽然我们只是下载了SDK通过一行脚本创建了
Android应用程序工程通过另一行完成了编译。
但也许还是会被认为过于麻烦因为需要进行字符界面的操作而且这种开发方式也不是常用的方式在Java环境下我们有Eclipse可用。
我们可以使用Eclipse的图形化开发工具配合ADT插件使用。
2.2 使用EclipseADT插件。
在
Android环境里可以使用Java世界里几乎一切的开发工具比如NetBeans等但Eclipse是
Android官方标准的开发方式。
使用Eclipse开发前面提到的开发所需SDK版本下载也是必须的然后还需要在Eclipse环境里加装ADT插件
Android Development Toolkit。
我们在Eclipse的菜单里选择”Help” à “Install New Software…”然后在弹出的对话框里的Workwith:输入ADT的发布地址https://dl-ssl.google.com/
android.eclipse回车则会得到下面的软件列表。
选择Select All将这些插件全都装上则得到了可用于
Android应用程序开发的环境。
这里还需要指定SDK的地址Windows或是Linux里会是在菜单“Window” à “Preferences”在MacOS里则会是”Eclipse” à“Preferences” 。
在弹出的对话框里选择
Android然后填入
Android SDK所保存的位置。
点击OK之后则可以进行
Android开发了。
选择”File” à “New”à “Project” à “
Android”在Eclipse 3.x版本里会是“
Android Project”在Eclipse 4.x版本里会是“
Android Application Project”。
如果我们需要创建跟前面字符界面下一模一样的应用程序工程则在弹出的创建应用程序对话框里填入如下的内容 然后我们选择Next一直到弹出最后界面提示让我们选择默认Activity的名字最后点击”Finish”我们就得到一个
Android应用程序工程同时在Eclipse环境里我们既可以通过图形化界面编辑Java代码也可以通过图形化的界面编辑工具来绘制图形界面。
注意: 如果
Android工程本身比较庞大则最好将Eclipse里的内存相关的配置改大。
在Windows和Linux里是修改eclipse里的eclipse.ini文件而在MacOS里则是修改Eclipse.app/Contents/MacOS/eclipse.ini。
一般会将如下的值加大成两倍 --launcher.XXMaxPermSize 512m -vmargs -Xms80m -Xmx1024m 我们得到工程目录在Eclipse环境里会是如下图所示的组织方式。
代码虽然是使用一模一样的编译方式唯一的改变是我们不再需要使用脚本来完成编译我们可以直接使用Eclipse的”Project”à“Build project”来完成编译过程。
如果我们使用默认设置则代码是使用自动编译的我们的每次修改都会触发增量式的编译。
我们从这些
android编程的过程看不出来
android跟别的Java编程模式有什么区别倒至少验证了我们前面对
android编程特点的猜想就是很简单。
如果同样我们使用Eclipse开发Java的图形界面程序需要大量地时间去熟悉API而在
Android这里学习的曲线被大大降低如果我们只是要画几个界面建立起简单的交互我们几乎无须学习编程。
而从上面的步骤我们大概也可以得到
Android开发的另一个好处就是极大的跨平台性它的开发流程里除了JDK没有提及任何的第三方环境需求于是这样的开发环境肯定可以在各种不同的平台执行。
这也是
Android上进行开发的好处之一跨平台支持WindowsLinux与MacOS三种。
我们再来看一个我们刚才创建的这个工程里我们怎么样进行下一步的开发。
在
Android开发里决定我们应用程序表现的也就是我们从一个.apk文件里看到的我们实际上只需要 ?? 修改AndroidManifest.xml文件。
AndroidManifest.xml是
Android应用程序的主控文件类型于Windows里的注册表我们通过它来配置我们的应用程序与系统相关的一些属性。
?? 修改UI显示。
在
Android世界里我们可以把UI编程与Java编程分开对待处理UI控件的语言我们可以叫它UI语言或是layout语言因为它们总是以layout类型的资源文件作为主入口的。
Android编程里严格地贯彻MVC的设计思路使我们得到了一个好处就是我们的UI跟要实现的逻辑没有任何必然联系我们可先去调整好UI显示而UI显示后台的实现逻辑则可以在后续的步骤里完成。
?? 改写处理逻辑的Java代码。
也就是我们MVC里的Controller与Model部分这些部分的内容如果与UI没有直接交互则我们可以放心大胆的改写存在交互的部分比如处理按钮的点击取回输入框里的文字等。
作为一个定位于拓展能力要求最高的智能手机操作系统
android肯定不会只实现画画界面而已会有强大的可开发能力在
android系统里我们可以开发企业级应用大型游戏以及完整的Office应用。
无论是通过tools/
android工具生成的
Android源代码目录还是通过Eclipse来生成的
Android源代码工程都需要进一步去自定义这个步骤来完成一个
Android应用程序。
当然还有一种特殊的情况就是这个源代码工程并非直接是一个
Android应用程序只是Unit Test工程或是库文件工作并不直接使用.apk文件这里则可能后续的编程工作会变得不同。
我们这里是分析
Android应用程序于是后面分别来看应用程序编程里的这三部分的工作如何进行。
2.3 AndroidManifest.xml 先来看看AndroidManifest.xml文件一般出于方便这一文件有可能也被称为manifest文件。
像我们前面的例子里的创建的
Android工程得到的AndroidManifest.xml文件就很简单 ltxml versionquot1.0quot encodingquotutf-8quotgt ltmanifest xmlns:androidquothttp://schemas.
android.com/apk/res/androidquot packagequotorg.lianlab.helloquot
android:versionCodequot1quot
android:versionNamequot1.0quotgt ltapplication
android:labelquotstring/app_namequotgt ltactivity
android:namequot.Helloworldquot
android:labelquotstring/app_namequotgt ltintent-filtergt ltaction
android:namequotandroid.intent.action.MAINquot /gt ltcategory
android:namequotandroid.intent.category.LAUNCHERquot /gt lt/intent-filtergt lt/activitygt lt/applicationgt lt/manifestgt 作为xml文件所有的ltgt都会是成对的比如我们看到的ltmanifestgtlt/manifestgt这被称为标签Tag。
标签可以包含子标签从而可以形成树型的结点关系。
如果没有子标签则我们也可以使用lt/gt来进行标识比如我们上面看到的ltactionandroid:name”
android.intent.action.MAIN” /gt。
ltmanifestgt是主标签每个文件只会有一个这是定义该应用程序属性的主入口包含应用程序的一切信息比如我们的例子里定义了xml的命名空间这个应用程序的包名以及版本信息。
ltapplicationgt则是用于定义应用程序属性的标签理论上可以有多个但多个不具有意义一般我们一个应用程序只会有一个在这个标签里我们可以定义图标应用程序显示出来的名.
上一篇:
基于Android手机平台的音乐播放器毕业设计论文
下一篇:
个人哪些方面的情况值得你在简历里做介绍?