余一

纸上得来终觉浅,绝知此事要躬行。

0%

开始启程

1.Android系统架构

Android大致可以分为4层架构:Linux内核层、系统运行库层、应用框架层和应用层

Linux内核层

​ Android系统是基于Linux内核的,这一层为Android设备的各种硬件提供了底层的驱动,如显示驱动、音频驱动、照相机驱动、蓝牙驱动、Wi-Fi驱动、电源管理等。

系统运行库层

​ 这一层通过一些C/C++库为Android系统提供了主要的特性支持。如SQLite库提供了数据库的支持,OpenGL|ES库提供了3D绘图的支持,Webkit库提供了浏览器内核的支持等。

​ 在这一层还有Android运行时库,它主要提供了一些核心库,允许开发者使用Java语言来编写Android应用。另外,Android运行时库中还包含了Dalvik虚拟机(5.0系统之后改为ART运行环境),它使得每一个Android应用都能运行在独立的进程中,并且拥有一个自己的虚拟机实例。相较于Java虚拟机,Dalvik和ART都是专门为移动设备定制的,它针对手机内存、CPU性能有限等情况做了优化处理。

应用框架层

​ 这一层主要提供了构建应用程序时可能用到的各种API,Android自带的一些核心应用就是使用这些API完成的,开发者可以使用这些API来构建自己的应用程序。

应用层

​ 所有安装在手机上的应用程序都是属于这一层的,比如系统自带的联系人、短信等程序,或者是你从Google Play上下载的小游戏,当然还包括你自己开发的程序。

2.Android已发布的版本

  • 2008年9月 Google正式发布了Android 1.0系统
  • 2011年2月 Google发布了Android3.0系统
  • 2014年10月 Google发布了Android5.0系统 API等级 21
  • 2019年9月 Google发布了Android10.0系统 API等级 29
  • 2020年9月 Google发布了Android11.0系统 API等级 30
  • 2021年10月 Google发布了Android12.0系统 API等级 31

3.Android应用框架提供哪些东西

四大组件

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

丰富的系统控件

SQLite数据库

​ Android系统还自带了这种轻量级、运算速度极快的嵌入式关系型数据库。它不仅支持标准的SQL语法,还可以通过Android封装好的API进行操作,让存储和读取数据变得非常方便。

强大的多媒体

​ Android系统还提供了丰富的多媒体服务,如音乐、视频、录音、拍照等,这一切你都可以在程序中通过代码进行控制,让你的应用变得更加丰富多彩。

4.分析第一个Android程序

Project模式的项目结构

  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. iml iml文件是所有IntelliJ IDEA项目都会自动生成的一个文件(Android Studio是基于IntelliJ IDEA开发的),用于标识这是一个IntelliJ IDEA项目,我们不需要修改这个文件中的任何内容。
  10. local.properties 这个文件用于指定本机中的Android SDK路径,通常内容是自动生成的,我们并不需要修改。除非你本机中的Android SDK位置发生了变化,那么就将这个文件中的路径改成新的位置即可。
  11. settings.gradle 这个文件用于指定项目中所有引入的模块。由于项目中只有一个app模块,因此该文件中也就只引入了app这一个模块。通常情况下,模块的引入是自动完成的,需要我们手动修改这个文件的场景可能比较少。

app目录

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

AppCompatActivity

​ AppCompatActivity是AndroidX中提供的一种向下兼容的Activity,可以使Activity在不同系统版本中的功能保持一致性。而Activity类是Android系统提供的一个基类,我们项目中所有自定义的Activity都必须继承它或者它的子类才能拥有Activity的特性(AppCompatActivity是Activity的子类)。

res目录

drawable目录也是相同的道理,虽然Android Studio没有帮我们自动生成,但是我们应该自己创建drawable-hdpi、drawable-xhdpi、drawable-xxhdpi等目录。drawable-xxhdpi目录是最主流的设备分辨率目录。

1
2
3
<resources>
<string name="app_name">ddPlayer</string>
</resources>

这里定义了一个应用程序名的字符串,我们有以下两种方式来引用它。

  • 在代码中通过R.string.app_name可以获得该字符串的引用。
  • 在XML中通过@string/app_name可以获得该字符串的引用。

基本的语法就是上面这两种方式,其中string部分是可以替换的,如果是引用的图片资源就可以替换成drawable,如果是引用的应用图标就可以替换成mipmap,如果是引用的布局文件就可以替换成layout,以此类推。

5.详解build.gradle文件

项目中有两个build.gradle文件,一个是在最外层目录下的,一个是在app目录下的。

最外层build.gradle

通常情况下,你并不需要修改这个文件中的内容,除非你想添加一些全局的项目构建配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath "com.android.tools.build:gradle:7.0.3"

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

task clean(type: Delete) {
delete rootProject.buildDir
}
  1. 两处repositories的闭包中都声明了google()和jcenter()这两行配置,对应了一个代码仓库,google仓库中包含的主要是Google自家的扩展依赖库,而jcenter仓库中包含的大多是一些第三方的开源库。
  2. dependencies闭包中使用classpath声明了插件,Gradle并不是专门为构建Android项目而开发的,Java、C++等很多种项目也可以使用Gradle来构建,因此如果我们要想使用它来构建Android项目,则需要声明com.android.tools.build:gradle:7.0.3这个插件。最后面的部分是插件的版本号,它通常和当前Android Studio的版本是对应的。

app/build.gradle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
plugins {
id 'com.android.application'
}

android {
compileSdk 32
defaultConfig {
applicationId "com.xixun.mvvmstudy"
minSdk 21
targetSdk 32
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

dataBinding {
enabled = true
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}

dependencies {
implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.3'
implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
implementation 'androidx.appcompat:appcompat:1.3.0-alpha02'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
  1. 第一行应用了一个插件,一般有两种值可选:com.android.application表示这是一个应用程序模块,com.android.library表示这是一个库模块。二者最大的区别在于,应用程序模块是可以直接运行的,库模块只能作为代码库依附于别的应用程序模块来运行。

  2. android闭包中又嵌套了一个defaultConfig闭包,defaultConfig闭包中可以对项目的更多细节进行配置。

    • applicationId是每一个应用的唯一标识符,绝对不能重复,默认会使用我们在创建项目时指定的包名,如果你想在后面对其进行修改,那么就是在这里修改的。
    • minSdk用于指定项目最低兼容的Android系统版本,这里指定成21表示最低兼容到Android 5.0系统。
    • targetSdk 指定的值表示你在该目标版本上已经做过了充分的测试,系统将会为你的应用程序启用一些最新的功能和特性。比如Android 6.0系统中引入了运行时权限这个功能,如果你将targetSdkVersion指定成23或者更高,那么系统就会为你的程序启用运行时权限功能。
    • versionCode用于指定项目的版本号,versionName用于指定项目的版本名。
    • testInstrumentationRunner用于在当前项目中启用JUnit测试,你可以为当前项目编写测试用例,以保证功能的正确性和稳定性。
  3. buildTypes闭包中用于指定生成安装文件的相关配置,通常只会有两个子闭包:一个是debug,一个是release。debug闭包用于指定生成测试版安装文件的配置,release闭包用于指定生成正式版安装文件的配置。另外,debug闭包是可以忽略不写的,因此我们看到上面的代码中就只有一个release闭包。

    • minifyEnabled用于指定是否对项目的代码进行混淆,true表示混淆,false表示不混淆。
    • proguardFiles用于指定混淆时使用的规则文件,这里指定了两个文件:第一个proguard-android-optimize.txt是在< AndroidSDK>/tools/proguard目录下的,里面是所有项目通用的混淆规则;第二个proguard-rules.pro是在当前项目的根目录下的,里面可以编写当前项目特有的混淆规则。通过Android Studio直接运行项目生成的都是测试版安装文件
  4. dependencies闭包。这个闭包的功能非常强大,它可以指定当前项目所有的依赖关系。通常Android Studio项目一共有3种依赖方式:本地依赖、库依赖和远程依赖。本地依赖可以对本地的jar包或目录添加依赖关系,库依赖可以对项目中的库模块添加依赖关系,远程依赖则可以对jcenter仓库上的开源项目添加依赖关系。

    • 加上声明后,Gradle在构建项目时会首先检查一下本地是否已经有这个库的缓存,如果没有的话则会自动联网下载,然后再添加到项目的构建路径中。
    • 库依赖声明基本格式是implementation project后面加上要依赖的库的名称,比如有一个库模块的名字叫helper,那么添加这个库的依赖关系只需要加入implementationproject(‘:helper’)这句声明即可。

6.日志

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