Android大致可以分为四层架构:Linux内核层、系统运行库层、应用框架层和应用层。
Android当下主流版本
目前4.0以上的系统已经占据了超过98%的Android市场份额,所以我们主要开发的程序只能面向4.0以上的系统。
四大组件
丰富的系统控件
Android系统为开发者提供了丰富的系统控件,使得我们可以很轻松地编写出漂亮的界面。当然,如果你不满足于系统自带的控件效果,也完全可以定制属于自己的空间。
SQLite数据库
Android系统还自带了这种轻量级、运算速度极快的嵌入式关系型数据库。它不仅支持标准的SQL语法,还可以通过Android封装好的API进行操作,让存储和读取数据变得
非常方便。
强大的多媒体
Android系统还提供了丰富的多媒体服务,如音乐、视频、录音、拍照、闹铃,等等,这一切你都可以在程序中通过代码进行控制,让你的应用变得更加丰富多彩。
地理位置定位
移动设备和PC相比起来,地理位置定位功能应该可以算是很大的一个亮点。现在的Android手机都内置有GPS,走到哪里都可以定位到自己的位置,发挥你的想象就可以做出创意十足的应用,如果再结合功能强大的地图功能,LBS这一领域潜力无限。
开发Android程序需要准备的工具
按照网上的指示安装Android Studio即可
(注意:由于我之前安装过一次,在第二次安装时因为SDK路径未能够正确导入(以前第一次安装时留下的SDK,卸载时依旧留在系统中)以至于打开Android时出现问题;
解决方法:进入Android Studio后,找到File->Settings->Apperance & Behavior ->System Settings->Android SDK目录,在Android SDK Location一栏中选择安装Android Studio时附带的SDK目录(我的SDK安装目录是G:\AndroidSDK)
Android Studio的欢迎界面
在Android Studio的欢迎界面,点击Start a new Android Studio project,会打开一个新建项目的界面。
Android Studio的模板选择界面
在上一个界面点击Next后,在这个界面我们可以选择一种模板。可以看到,Android Studio提供了很多种内置模板,这里直接选择Empty Activity来创建一个空的活动就可以了。
Android Studio的模板编辑界面
继续点击Next,可以给创建的活动和布局命名。
其中:
Android Studio的模拟器按钮
观察Android Studio顶部工具栏中的图标,该按钮是用于创建和启动模拟器的,点击该按钮,即可打开模拟器的界面。
Android Studio的模拟器界面
进行一系列的配置过后,可以看到现在模拟器列表中已经性存在一个创建好的模拟器你设备了,点击Actions栏目中最左边的三角形按钮可启动模拟器。模拟器会像手机一样,有个开机的过程。
Android Studio的运行项目按钮
观察Android Studio顶部工具栏中的图标,其中左边的锤子按钮是用来编译项目的,中间的下拉列表是用来选择运行哪一个项目的,通常app就是当前的主项目,右边的三角形项目是用来运行项目的。
选择运行设备
以看到,我们创建的模拟器是在线的,点击OK按钮,稍微等待一会儿,HelloWorld项目就会运行到模拟器上了。
模拟器运行界面
可以看到,模拟器已经安装上HelloWorld这个应用了。
Android Studio的项目结构
任何一个新建的项目都会默认使用Android模式的项目构造,但这并不是项目真实的目录结构,而是被Android Studio转换过的。这种项目结构简介明了,适合进行快速开发,但是对于新手来说可能并不易于理解。
点击图中的Android区域可以切换项目结构模式,这里讲项目结构模式切换成Project,这就是项目真实的目录结构了。
Android Studio的外层目录结构讲解
现在整个项目的外层目录结构已经介绍完了,你会发现,除了app目录之外,大多数的文件和目录都是自动生成的,我们并不需要进行修改。想必你已经猜到了,app目录下的内容才是我们以后的工作重点。
分析项目是如何运行的
首先打开AndroidManifest.xml文件,从中可以找到如下代码:
这段代码表示对HelloWorldActivity这个活动进行注册,没有在AndroidManifest.xml里注册的活动是不能使用的。
其中,intent-filter里的两行代码非常重要:
和
表示HelloWorldActivity是这个项目的主活动,在手机上点击应用图标,首先启动的就是这个活动。
那HelloWorldActivity具体又有什么作用呢?活动是Android应用程序的门面,凡是在应用中你看得到的东西,都是放在活动中的。因此你看到的页面,其实就是HelloWorldActivity这个活动。
打开HelloWorldActivity.java,代码如下所示:
我们可以看到,HelloWorldActivity是继承自AppCompatActivity的,这是一种向下兼容的Activity,可以将Activity在各个系统版本中增加的特性和功能最低兼容到Android2.1系统。
Activity是Android提供的一个活动基类,我们项目中所有的活动都必须继承它或者它的子类才能拥有活动的特性(AppCompatActivity是Activity的子类)。
然后可以看到HelloWorldActivity中有一个onCreate()方法,这个方法是一个活动被创建时必定要执行的方法,其中只有两行代码,并且没有Hello World!的字样。
Android程序的设计讲究逻辑和视图分离,比较通用的编写界面的方式是:在布局文件中编写界面,然后在活动中引入进来。可以看到,在onCreate()方法中的第二行调用了setContentView()方法,就是这个方法给当前的活动引入了一个hello_world_layout布局,那Hello World!一定就是这里定义的了。
布局文件都是定义在res/layout目录下的,当你展开layout目录,你会看到hello_world_layout.xml这个文件,打开该文件并切换到Text视图,代码如下所示:
我们可以看到,代码中有一个TextView,这是Android系统提供的一个控件,用于在布局中显示文字的。事实上,Hello World!的字样就是通过android:text="Hello World!"
这句代码定义的。
如果你展开res目录看一下,其实里面的东西还是挺多的,很容易让人看得眼花缭乱。
所有以drawable开头的文件夹都是用来放图片的,所有以mipmap开头得到文件都是用来放应用图标的,所有以values开头的文件夹都是用来放字符串、样式、颜色等配置的,layout文件夹是用来放布局文件的。
之所以有这么多mipmap开头的文件夹,其实主要是为了让程序能够更好地兼容各种设备。drawable文件夹也是相同的道路,虽然Android Studio没有帮我们自动生成,但是我们有概念股自己创建drawable-hdpi、drawable-xhdqi、drawable-xxhdpi等文件夹。在制作程序的时候最好能够给同一张图片提供几个不同分辨率的版本,分别放在这些文件夹下,然后当程序运行的时候,会自动根据当前运行设备分辨率的高低选择加载哪个文件夹的图片。
打开res/values/strings.xml文件,内容如下所示:
可以看到,这里定义了一个应用程序名的字符串,我们有以下两种方式来引用它:
android:icon
属性来指定的,应用的名称则是通过android:label
属性指定的。不同于Eclipse,Android Studio是采用Gradle来构建项目的。Gradle是一个非常先进的项目构建工具,它使用了一种基于Groovy的领域特定语言(DSL)来声明项目设置,摒弃了传统基于XML(如Ant和Maven)的各种繁琐配置。
在之前我们可以看到,HelloWorld项目中有两个build.gradle文件,一个是在最外层目录下的,一个是在app目录下的。这两个文件对构建Android Studio项目都起到了至关重要的作用,下面我们就来对这两个文件中的内容进行详细的分析。
先来看一下最外层目录下的build.gradle文件,代码如下所示:
这些代码都是自动生成的,虽然语法结构看上去可能有点难以理解,但是如果我们忽略语法结构,只看最关键的部分,其实还是很好懂的。
其中,两处repositories闭包中都声明了jcenter()这行配置,它是一个代码托管仓库,很多Android开源项目都会选择将代码托管到jcenter上,声明了这行配置之后,我们就可以在项目中轻松引用任何jcenter上的开源项目了。
接下来,dependencies闭包中使用classpath声明了一个Gradle插件。为什么要声明这个插件呢?因为Gradle并不是专门为构建Android项目而开发的,Java、C++等很多种项目都可以使用Gradle来构建。因此如果我们想要使用它来构建Android项目,则需要声明com.android.tools.build:gradle:2.2.0这个插件。其中,最后的部分是插件的版本号。
这样我们就将最外层目录下的build.gradle文件分析完了,通常情况下你并不需要修改这个文件中的内容,除非你想添加一些全局的项目构建配置。
下面我们再来看一下app目录下的build.gradle文件,代码如下所示:
首先第一行应用了一个插件,一般有两种值可选:com.android.application表示这是一个应用程序模块,com.android.library表示这是一个库模块。应用程序模块和库模块的最大区别在于:一个是可以直接运行的,一个只能作为代码库依附于别的应用程序模块来运行。
接下来是一个大的android闭包,在这个闭包中我们可以配置项目构建的各种属性。其中:
然后我们看到,这里在android闭包中又嵌套了一个defaultConfig闭包,这个闭包可以对项目的更多细节进行配置。其中:
分析完了这个闭包,接下来我们看一下buildTypes闭包。这个闭包的功能非常强大,它可以指定当前项目所有的依赖关系。通常Android Studio项目一共有三种依赖关系:
8. 本地依赖:可以对本地的Jar包或目录添加依赖关系。
9. 库依赖:可以对项目中的库模块添加依赖关系。
10. 远程依赖:可以对jcenter库上的开源项目添加依赖关系。
观察一下dependencies闭包中的配置,第一行的compile fileTree就是一个本地依赖声明,它表示将libs目录下所有.jar后缀的文件都添加到项目的构建路径当中。而第二行的compile则是远程依赖声明,com.android.support:appcompat-v7:24.2.1就是一个标准的远程依赖库格式,其中:
加上这句声明后,Gradle在构建项目时会首先检查一下本地是否已经有这个库的缓存,如果没有的话则会去自动联网下载,然后再添加到项目的构建路径当中。至于库依赖声明这里没有用到,它的基本格式是compile project后面加上要依赖的库名称,比如说有一个库模块的名字叫helper,那么添加这个库的依赖关系只需要加入compile project(’:helper’)这句声明即可。
另外,剩下的一句testCompile是用于声明测试用例库的。
Android中的日志工具类是Log(android.util.Log),这个类中提供了如下5个方法来供我们打印日志:
在真正的项目开发中,是极度不建议使用System.out.println()方法的,如果你在公司的项目中经常使用这个方法,就很有可能要挨骂了。
System.out.println()方法虽然可以实现快捷使用,但是具有日志打印不可控制、打印时间无法确定、不能添加过滤器、日志没有级别区分的缺点。
上面提到的快捷使用,在Android Studio当中也是有的,比如你想打印一条debug级别的日志,那么只需要输入logd,然后按下Tab键,就会帮你自动补全一条完整的打印语句。输入logi,然后按下Tab键,会自动补全一条info级别的打印日志。输入logw,按下Tab键,会自动补全一条warn级别的打印日志,以此类推。
另外,由于Log的所有打印方法都要求传入一个tag参数,每次写一遍显然太过麻烦。这里还有一个小技巧,我们在onCreate()方法的外面输入logt,然后按下Tab键,这是就会以当前的类名作为值自动生成一个TAG常量,如下所示:
除了快捷输入之外,logcat中还能很轻松地添加过滤器,你可以在下图中看到我们目前所有的过滤器:
目前只有3个过滤器,其中:
除此之外,我们还可以自定义过滤器。点击上图中的Edit Filter Configuration,会弹出一个过滤器配置页面:
我们给过滤器起名为Data,并且让它对名为data的tag进行过滤。点击OK,你就会发现已经多出了一个Data过滤器:
当你切换到这个过滤器的时候,你会发现刚才在onCreate()方法里打印的日志没了,这是因为Data这个过滤器只会显示tag名称为data的日志。你可以尝试在onCreate()方法中把打印日志的语句改成Log.d(“data”,“onCreate execute”),然后再次运行程序,你就会在data过滤器下看到这行日志了。
看完了过滤器,再来看一下logcat中的日志级别控制吧。logcat中主要有5个级别,分别对应着1.4.1介绍的5歌方法,如图所示:
当前我们选中的级别是verbose,也就是最低等级。这意味着不管我们使用哪一个方法打印日志,这条日志都一定会显示出来。而如果我们将级别选中为debug,这时只有我们使用debug及以上级别方法打印的日志才会显示出来,以此类推。
日志级别控制的好处就是,你可以很快找到你所关心的那些日志。
最后我们再来看一下关键字过滤。如果使用过滤器加日志级别控制还是不能锁定到你想查看的日志内容的话,那么还可以通过关键字进行进一步的过滤,如下图所示:
我们可以在输入框里输入关键字的内容,这里只有符合关键字条件的日志才会显示出来,从而能够快速定位到任何你想查看的日志。另外还有一点需要注意,关键字过滤是支持正则表达式的,有了这个特性,我们就可以构建出更加丰富的过滤条件。