《android第一行代码,第二版》学习笔记(一)

Android系统四大组件
分别是活动(Activity)、服务(Service)、广播接收器(Broadcast Receiver)和内容提供器(Content Provider)。
其中活动是所有Android应用程序的门面,凡是在应用中你看得到的东西,都是放在活动中的。而服务就比较低调了,你无法看到它,但它会一直在后台默默地运行,即使用户退出了应用,服务仍然是可以继续运行的。广播接收器允许你的应用接收来自各处的广播消息,比如电话、短信等,当然你的应用同样也可以向外发出广播消息。内容提供器则为应用程序之间共享数据提供了可能,比如你想要读取系统电话簿中的联系人,就需要通过内容提供器来实现。

创建你的第一个Android项目

  • Application name表示应用名称,此应用安装到手机之后会在手机上显示该名称
  • Company Domain表示公司域名
  • Package name表示项目的包名
  • Project location表示项目代码存放的位置
  • Activity Name表示活动的名字
  • Layout Name表示布局的命名

分析你的第一个Android程序

  1. .gradle和.idea:这两个目录下放置的都是Android Studio自动生成的一些文件
  2. app:项目中的代码、资源等内容几乎都是放置在这个目录下
  3. build:包含了一些在编译时自动生成的文件
  4. gradle:这个目录下包含了gradle wrapper的配置文件,使用gradle wrapper的方不需要提前将gradle下载好,而是会自动根据本地的缓存情况决定是否需要联网下载gradle。Android Studio默认没有启用gradle wrapper的方式,如果需要打开,可以点击Android Studio导航栏→File→Settings→Build, Execution, Deployment→Gradle,进行配置更改。
  5. .gitignore:用来将指定的目录或文件排除在版本控制之外的
  6. build.gradle:这是项目全局的gradle构建脚本,通常这个文件中的内容是不需要修改的
  7. gradle.properties:全局的gradle配置文件,在这里配置的属性将会影响到项目中所有的gradle编译脚本。
  8. gradlew和gradlew.bat:这两个文件是用来在命令行界面中执行gradle命令的,其中gradlew是在Linux或Mac系统中使用的,gradlew.bat是在Windows系统中使用的。
  9. HelloWorld.iml:iml文件是所有IntelliJ IDEA项目都会自动生成的一个文件(Android Studio是基于IntelliJIDEA开发的),用于标识这是一个IntelliJ IDEA项目,我们不需要修改这个文件中的任何内容
  10. local.properties:这个文件用于指定本机中的Android SDK路径,通常内容都是自动生成的,我们并不需要修改。除非你本机中的Android SDK位置发生了变化,那么就将这个文件中的路径改成新的位置即可。
  11. settings.gradle:这个文件用于指定项目中所有引入的模块。

app目录下的结构

  • build:这个目录和外层的build目录类似,主要也是包含了一些在编译时自动生成的文件,不过它里面的内容会更多更杂,我们不需要过多关心。
  • libs:如果你的项目中使用到了第三方jar包,就需要把这些jar包都放在libs目录下,放在这个目录下的jar包都会被自动添加到构建路径里去。
  • androidTest:此处是用来编写Android Test测试用例的,可以对项目进行一些自动化测试。
  • java:java目录是放置我们所有Java代码的地方,展开该目录,你将看到我们刚才创建的HelloWorldActivity文件就在里面。
  • res:项目中使用到的所有图片、布局、字符串等资源都要存放在这个目录下。当然这个目录下还有很多子目录,图片放在drawable目录下,布局放在layout目录下,字符串放在values目录下。
  • AndroidManifest.xml:Android项目的配置文件,你在程序中定义的所有四大组件都需要在这个文件里注册,另外还可以在这个文件中给应用程序添加权限声明。
  • test:用来编写Unit Test测试用例的,是对项目进行自动化测试的另一种方式。
  • .gitignore:文件用于将app模块内的指定的目录或文件排除在版本控制之外,作用和外层的.gitignore文件类似。
  • app.iml:IntelliJ IDEA项目自动生成的文件,我们不需要关心或修改这个文件中的内容。
  • build.gradle:这是app模块的gradle构建脚本,这个文件中会指定很多项目构建相关的配置。
  • proguard-rules.pro:这个文件用于指定项目代码的混淆规则,当代码开发完成后打成安装包文件,如果不希望代码被别人破解,通常会将代码进行混淆,从而让破解者难以阅读。

AndroidManifest.xml文件


	
		
		
	

这段代码表示对HelloWorldActivity这个活动进行注册,没有在AndroidManifest.xml里注册的活动是不能使用的。其中intent-filter 里的两行代码非常重要,

 

表示HelloWorldActivity是这个项目的主活动。

HelloWorldActivity

public class HelloWorldActivity extends AppCompatActivity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.hello_world_layout);
	}
}

HelloWorldActivity是继承自AppCompatActivity的,这是一种向下兼容的Activity,可以将Activity在各个系统版本中增加的特性和功能最低兼容到Android 2.1系统。Activity是Android系统提供的一个活动基类,我们项目中所有的活动都必须继承它或者它的子类
才能拥有活动的特性(AppCompatActivity 是Activity的子类)。然后可以看到
HelloWorldActivity中有一个onCreate() 方法,这个方法是一个活动被创建时必定要执行的方法,其中只有两行代码,并且没有Hello World!的字样。

其实Android程序的设计讲究逻辑和视图分离,因此是不推荐在活动中直接编写界面的,更加通用的一种做法是,在布局文件中编写界面,然后在活动中引入进来。可以看到,在onCreate() 方法的第二行调用了setContentView() 方法,就是这个方法给当前的活动引入了一个hello_world_layout布局,那Hello World!一定就是在这里定义的了!我们快打开这个文件看一看。

布局文件都是定义在res/layout目录下的,当你展开layout目录,你会看到hello_world_layout.xml这个文件



	

详解项目中的资源
res目录下的结构

所有以drawable开头的文件夹都是用来放图片的,所有以mipmap开头的文件夹都是用来放应用图标的,所有以values开头的文件夹都是用来放字符串、样式、颜色等配置的,layout文件夹是用来放布局文件的。

之所以有这么多mipmap开头的文件夹,其实主要是为了让程序能够更好地兼容各种设备。drawable文件夹也是相同的道理,虽然Android Studio没有帮我们自动生成,但是我们应该自己创建drawable-hdpi、drawable-xhdpi、drawable-xxhdpi等文件夹

打开res/values/strings.xml文件:


	HelloWorld

可以看到,这里定义了一个应用程序名的字符串,我们有以下两种方式来引用它。
在代码中通过R.string.app_name 可以获得该字符串的引用
在XML中通过@string/app_name 可以获得该字符串的引用。
基本的语法就是上面这两种方式,其中string 部分是可以替换的,如果是引用的图片资源就可以替换成drawable ,如果是引用的应用图标就可以替换成mipmap ,如果是引用的布局文件就可以替换成layout ,以此类推。

简单的例子来帮助你理解,打开AndroidManifest.xml文件,找到如下代码:


	...

HelloWorld项目的应用图标就是通过android:icon 属性来指定的,应用的名称则是通
过android:label 属性指定的。

详解build.gradle文件
Android Studio是采用Gradle来构建项目的。Gradle是一个非常先进的项目构建工具,它使用了一种基于Groovy的领域特定语言(DSL)来声明项目设置,摒弃了传统基于
XML(如Ant和Maven)的各种烦琐配置。

HelloWorld项目中有两个build.gradle文件,一个是在最外层目录下的,一个是在app目录下的。这两个文件对构建Android Studio项目都起到了至关重要的作用,下面我们就来对这两个文件中的内容进行详细的分析。

最外层目录下的build.gradle文件

buildscript {
	repositories {
		jcenter()
	}
	dependencies {
		classpath 'com.android.tools.build:gradle:2.2.0'
	}
}
allprojects {
	repositories {
		jcenter()
	}
}

这些代码都是自动生成的,虽然语法结构看上去可能有点难以理解,但是如果我们忽略语法结构,只看最关键的部分,其实还是很好懂的。

首先,两处repositories 的闭包中都声明了jcenter() 这行配置,那么这个jcenter是什么
意思呢?其实它是一个代码托管仓库,很多Android开源项目都会选择将代码托管到jcenter上,声明了这行配置之后,我们就可以在项目中轻松引用任何jcenter上的开源项目了。

接下来,dependencies 闭包中使用classpath 声明了一个Gradle插件。为什么要声明这个插件呢?因为Gradle并不是专门为构建Android项目而开发的,Java、C++等很多种项目都可以使用Gradle来构建。因此如果我们要想使用它来构建Android项目,则需要声明com.android.tools.build:gradle:2.2.0 这个插件。其中,最后面的部分是插件的
版本号,我在写作本书时最新的插件版本是2.2.0。

app目录下的build.gradle文件

apply plugin: 'com.android.application'

android {
	compileSdkVersion 24
	buildToolsVersion "24.0.2"
	defaultConfig {
		applicationId "com.example.helloworld"
		minSdkVersion 15
		targetSdkVersion 24
		versionCode 1
		versionName "1.0"
	}
	buildTypes {
			release {
				minifyEnabled false
				proguardFiles getDefaultProguardFile('proguard-android.txt'),
					'proguard-rules.pro'
			}
	}
}

dependencies {
	compile fileTree(dir: 'libs', include: ['*.jar'])
	compile 'com.android.support:appcompat-v7:24.2.1'
	testCompile 'junit:junit:4.12'
}

首先第一行应用了一个插件,一般有两种值可选:com.android.application 表示这是一个应用程序模块,com.android.library 表示这是一个库模块。应用程序模块和库模块的最大区别在于,一个是可以直接运行的,一个只能作为代码库依附于别的应用程序模块来运行。

接下来是一个大的android闭包 ,在这个闭包中我们可以配置项目构建的各种属性。其
中,compileSdkVersion 用于指定项目的编译版本,这里指定成24表示使用Android 7.0系统的SDK编译。buildToolsVersion 用于指定项目构建工具的版本,目前最新的版本就是24.0.2,如果有更新的版本时,Android Studio会进行提示。

然后我们看到,这里在android闭包中又嵌套了一个defaultConfig闭包 ,defaultConfig闭包中可以对项目的更多细节进行配置。其中,applicationId 用于指定项目的包名,前面我们在创建项目的时候其实已经指定过包名了,如果你想在后面对其进行修改,那么就是在这里修改的。minSdkVersion 用于指定项目最低兼容的Android系统版本,这里指定成15表示最低兼容到Android 4.0系统。targetSdkVersion 指定的值表示你在该目标版本上已经做过了充分的测试,系统将会为你的应用程序启用一些最新的功能和特性。比如说Android 6.0系统中引入了运行时权限这个功能,如果你将targetSdkVersion 指定成23或者更高,那么系统就会为你的程序启用运行时权限功能,而如果你将targetSdkVersion 指定成22,那么就说明你的程序最高只在Android 5.1系统上做过充分的测试,Android 6.0系统中引入的新功能自然就不会启用了。剩下的两个属性都比较简单,versionCode 用于指定项目的版本号,versionName 用于指定项目的版本名,这两个属性在生成安装文件的时候非常重要,我们在后面都会学到。

分析完了defaultConfig闭包,接下来我们看一下buildTypes闭包 。buildTypes闭包中用于指定生成安装文件的相关配置,通常只会有两个子闭包,一个是debug,一个是release。debug闭包用于指定生成测试版安装文件的配置,release闭包用于指定生成正式版安装文件的配置。另外,debug闭包是可以忽略不写的,因此我们看到上面的代码中就只有一个release闭包。下面来看一下release闭包中的具体内吧,minifyEnabled 用于指定是否对项目的代码进行混淆,true表示混淆,false 表示不混淆。proguardFiles 用于指定混淆时使用的规则文件,这里指定了两个文件,第一个proguard-android.txt 是在Android SDK目录下的,里面是所有项目通用的混淆规则,第二个proguard-rules.pro 是在当前项目的根目录下的,里面可以编写当前项目特有的混淆规则。需要注意的是,通过Android Studio直接运行项目生成的都是测试版安装文件,关于如何生成正式版安装文件我们将会在第15章中学习。

这样整个android闭包中的内容就都分析完了,接下来还剩一个dependencies闭包 。这个闭包的功能非常强大,它可以指定当前项目所有的依赖关系。通常Android Studio项目一共有3种依赖方式:本地依赖、库依赖和远程依赖。本地依赖可以对本地的Jar包或目录添加依赖关系,库依赖可以对项目中的库模块添加依赖关系,远程依赖则可以对jcenter库上的开源项目添加依赖关系。观察一下dependencies闭包中的配置,第一行的compile fileTree 就是一个本地依赖声明,它表示将libs目录下所有.jar后缀的文件都添加到项目的构建路径当中。而第二行的compile 则是远程依赖声明,com.android.support:appcompat-v7:24.2.1 就是一个标准的远程依赖库格式,其中com.android.support 是域名部分,用于和其他公司的库做区分;appcompat-v7 是组名称,用于和同一个公司中不同的库做区分;24.2.1是版本号,用于和同一个库不同的版本做区分。加上这句声明后,Gradle在构建项目时会首先检查一下本地是否已经有这个库的缓存,如果没有的话则会去自动联网下载,然后再添加到项目的构建路径当中。至于库依赖声明这里没有用到,它的基本格式是compile project 后面加上要依赖的库名称,比如说有一个库模块的名字叫helper,那么添加这个库的依赖关系只需要加compile
project(’:helper’) 这句声明即可。另外剩下的一句testCompile 是用于声明测试用例
库的,这个我们暂时用不到,先忽略它就可以了。

使用Android的日志工具Log
Android中的日志工具类是Log(android.util.Log),这个类中提供了如下5个方法来供我们打印日志。

  • Log.v() 。用于打印那些最为琐碎的、意义最小的日志信息。对应级别verbose,是
    Android日志里面级别最低的一种。
  • Log.d() 。用于打印一些调试信息,这些信息对你调试程序和分析问题应该是有帮助的。对应级别debug,比verbose高一级。
  • Log.i() 。用于打印一些比较重要的数据,这些数据应该是你非常想看到的、可以帮你分析用户行为数据。对应级别info,比debug高一级。
  • Log.w() 。用于打印一些警告信息,提示程序在这个地方可能会有潜在的风险,最好去修复一下这些出现警告的地方。对应级别warn,比info高一级。
  • Log.e() 。用于打印程序中的错误信息,比如程序进入到了catch语句当中。当有错误信息打印出来的时候,一般都代表你的程序出现严重问题了,必须尽快修复。对应级别error,比warn高一级。

打开HelloWorldActivity,在onCreate() 方法中添加一行打印日志的语句

protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.hello_world_layout);
	Log.d("HelloWorldActivity", "onCreate execute");
}

Log.d() 方法中传入了两个参数:第一个参数是tag ,一般传入当前的类名就好,主要用于对打印信息进行过滤;第二个参数是msg ,即想要打印的具体的内容。

你可能感兴趣的:(Android基础笔记)