最近鸿蒙很火,加上我之前一直就对移动开发有些兴趣,后来突然想到,安卓开发就是直接用Java写,无需再学新语言,就准备开始搞安卓开发,Android Studio的最新版本已经到了4.2,看了一下京东上中文的书还没有讲到这么新的版本.
后来在https://1lib.us/book/10985855/714a01上找到了这本Android Studio 4.1 Development Essentials,翻了一下目录,发现超级详细,就准备用这本书来入门一下安卓开发了.
安装Android Studio
根据书里的提示,在https://developer.android.com/studio/archive可以找到历史版本下载,就老实下载了4.1.2正式版来用.
安装的时候按照书上的提示,一并勾上了Android Virtual Device.
之后启动程序,初始化界面按过之后,需要到Settings-Android SDK中下载最新的SDK,首先是SDK Platforms,要把最新的11.0(R)和10.0(Q)下载回来.之后切换到SDK Tools,确保安装了下列内容:
- Android SDK Build-tools
- Android Emulator
- Android SDK Platform-tools
- Android SDK Tools
- Google Play Services
- Intel x86 Emulator Accelerator (HAXM installer)
- Google USB Driver (Windows only)
- Layout Inspector image server
配置PATH
在刚才的页面上,上面会显示Android SDK Location,我的目录是:D:\Software\sdk,需要把如下几个地址加到PATH中:
- D:\Software\sdk\tools
- D:\Software\sdk\tools\bin
- D:\Software\sdk\platform-tools
配置模拟器
再在系统菜单中的AVD Manager中下载并配置一下Android模拟器即可,一般可以选择Pixel4,下载好之后,就算完成了准备,实际在编写第一个项目的时候,还会自动下载Gradle,这些都是IDE自动配置,所以都很方便.
Android系统架构
之前我买过一本Android Studio 开发实战 从零基础到App上线,不过这本书直接针对编写App来讲,对于不了解安卓系统的我还是比较迷糊,相比之下老外这本书就详细多了,还介绍了安卓的系统架构,这里我也记录一下.
安卓系统的架构是由一堆软件栈组成的,包含一个操作系统,运行时环境,中间件,服务和库.整体的架构图如下:

最底层是一个Linux核心,然后是Android运行时环境,之后是应用程序框架,最上边就是我们要编写的应用,这里也包含一些系统应用.
Linux Kernel
在整个架构最底层的,就是一个Linux核心,安卓的Linux核心版本是2.6版,提供了内存管理,电源管理,多任务,底层硬件驱动等一系列操作系统内核应该提供的内容.安卓只使用了Linux内核而不是一个完整的Linux系统,因为完整的Linux系统很庞大,而且有很多功能手机用不到,对于Android来说最重要的是,其实是基于Linux内核之上提供的Android运行时环境,也就是俗称的ART.
Android Runtime
当使用Android Studio写成一个APP的时候,这个App被编译成字节码格式,当这个App被放到实际的机器上运行的时候,ART会将其编译成设备处理器的原生指令,也就是Linux系统的可执行文件ELF格式,后边当这个应用再次被运行的时候,实际运行的是ELF可执行文件,这样速度会比较快.可以说Android Runtime是安卓之所以被称为安卓系统的关键.
Android Libraries
安卓运行时环境依赖很多安卓库,安卓库也是安卓操作系统特有的,在开发工具里也带有这些库.这些库是一套基于Java语言的库,所以你可能猜到了,ART是类似于Java虚拟机的东西,基本上没错.安卓库对一些系统功能提供基础支持.
常见的对于开发者比较重要的库有:
android.app,针对所有的安卓应用提供基础支持android.content,提供应用间,应用与组件之间访问,发布,传递消息的功能android.database,提供访问数据库的功能,包括管理SQLite的库android.graphics,底层的2D绘图库android.hardware,访问硬件的接口,比如访问加速度仪或者陀螺仪等设备android.opengl,3D绘图库android.os,操作系统提供的服务,比如消息,系统服务,进程间通信android.net,网络库,比如使用wifi功能就要依赖于android.net.wifi库android.print,提供打印功能android.provider,提供访问标准安卓内容提供者的功能,比如通信录和联系人android.text,在屏幕上渲染文字的功能android.util,辅助工具类,提供字符串和数值转换,XML解析,时间日期功能等的辅助库android.view,提供应用的基础渲染android.widget,提供预先构建好的基础用户界面模块,比如按钮,标签,列表,布局等android.webkit,提供在应用内实现Web浏览功能的库
上边这些都是Java库,然而这些库,虽然都可以通过Java API来访问,其核心其实全部由C或者C++写成,不难想象,Linux的核心库也是如此.所以实际上这些Java库只是外边套了一层Java而已,其核心都是C系语言写成.
一般我们在开发的时候,都是通过Java来访问,在特殊的情况下,可以通过Android Native Development Kit,通过JNI来原生访问这些库.
Android Framework
这一层实际上是对App的运行直接提供支持的库,或者更常见的说法是对应用提供的服务.安卓的理念是:安卓应用是一个可重用,可替代的组件,一个安卓应用可以把它的功能发布到系统中,让其他应用可以访问其API并使用其返回的数据,Android Framework就是以这个理念服务于运行于其上的所有应用提供服务的.
常见的服务有:
Activity Manager,控制应用的生命周期和Activity Stack,可以理解为页面的栈.Content Providers,向其他应用发布和共享数据Content Providers,向其他应用发布和共享数据Resource Manager,提供访问非代码集成的资源,比如字符串,颜色设置,用户界面布局等Notifications Manager,向用户展示系统通知和警告View System,创建用户界面的视图功能Package Manager,查找系统中安装的其他应用的信息Telephony Manager,提供电话功能Location Manager,提供定位功能
Applications
最上边就是应用,也就是我们要开发的应用.这一层还包括特定的系统实现的应用(比如系统集成的浏览器等应用),我们开发的应用,也称为第三方应用.
看完了系统的架构,再来看一下安卓应用的核心概念.
Android应用解剖
国内的书最大问题就是缺少前边这些铺垫,即使是初学者,也应该建立起整体的架构,进而再学习某一个部分.来看一下安卓应用中的核心概念.
Activity
熟悉面向对象开发语言的人,一般都会把数据和对应的操作封装到类中,然后通过对象来创建一个应用程序.安卓应用也是如此.安卓应用是由一个个可以复用,替换的组件组成,这个组件被称为Activity.
一般来说,一个Activity是一个独立的功能模块,一般是结合了一个单独的用户界面(或者说一屏)和对应的功能代码(一个Java类).比如一个电商应用,登录界面是一个Activity,登录成功之后进入首页,这个首页是另外一个Activity.
我们编写应用程序时候创建的所有Activity是Android系统库中的Activity的子类,所以每一个Activity都是独立于应用中的其他Activity的独立对象.一个Activity不能够直接访问其他Activity的方法和数据,而必须通过Intent和Content Provider才可以.这两个概念后边会详述.
在一个Activity中,可以切换到另外一个Activity的显示,就类似于WEB应用中,登录成功后跳转到首页.默认情况下,不能够从一个Activity向调用它的Activity返回数据,如果需要这种功能,一般会将这个Activity作为调用它的Activity的子Activity.
简单的来说,Activity就是一个独立的功能模块,一般由一屏用户界面加上一个对应的Java类组成,其实也很像Web开发,一个界面对应一个后端地址.
Fragment
上边刚说完,典型的情况是一个完整的用户界面加上对应的类,组成了一个Activity,不过在实际开发中,一般会将一个Activity再分成多个部分来开发,这每一个部分,就称为Fragment.
一个Fragment,一般由用户界面的一部分,加上对应的一个Java类(为Android系统包的Fragment类的子类)组成.
实际上可以看到,这种结构和Activity很类似,所以一个Activity可以理解为是Fragment的容器.有了Fragment之后,就更加灵活了,在一个Activity内,也可以拥有多个界面,或者多种形态的内容.
这里也很像Web开发,就类似于React的组件中再套组件.
Intent
Intent是连接不同的Activity,来完成整个应用的工作流的组件,可以认为是Activity之间交互的载体,Intent中可以定义需要完成什么操作,还可选地可以传递数据.
Intent可以是显式的,即启动一个指定的Activity,传输想要的数据,也可以是隐式的,指定要进行何种类型的操作,从而启动对应的Activity,在隐式的情况下,ART会解析Intent然后启动与之目的最符合的Activity.
我自己的理解,这玩意很像是WEB开发中的Model加上控制器的混合,在不同的URL间传递数据或者状态.
Broadcast Intent
这个也是一种Intent,只不过是向所有注册为对这个Inten感兴趣的其他应用进行广播.其他应用需要具备Intent Receiver.举个例子,安卓系统在系统接入电源的时候,熄屏亮屏的时候,就会发送Broadcast Intent,如果我们编写的程序有对应的Intent Receiver,就可以进行对应的动作.
Broadcast Intent可以是同时的,即一次性给所有Intent Receiver都发送,也可以是有序的,即先发个一个Intent Receiver,然后可以决定是废弃还是再发给下一个Intent Receiver.
Broadcast Receiver
Broadcast Receiver就是用来接受特定的Broadcast Intent的功能.Broadcast Receiver必须由一个应用进行注册,并使用一个Intent Filter来标明对哪种类型的Broadcast Intent感兴趣.
当对应的Broadcast Intent出现时,ART就会调用Broadcast Receiver,即使注册Broadcast Receiver的应用没有在运行,也会去调用.调用之后,Broadcast Receiver有5秒钟的时间完成任务(比如启动服务,发送通知给用户,更新数据库等).Broadcast Receiver是在后台运行的,不需要用户界面.
很显然,这就是一个发布-订阅模式,从交互层级来看,可以用于应用之间,以及系统级别的广播,让应用可以根据系统或者其他程序的变化来作出自己的反应.
Android Service
安卓服务都在后台运行,没有用户界面.可以由应用,Broadcast Receiver或者其他服务启动.一般来说,在后台一直提供服务,且不需要用户界面的程序,可以考虑写成服务.这个有点类似于Linux中把应用改成通过服务运行.
虽然服务没有用户界面,但依然可以使用toast或者其他方式通知用户.
ART会把安卓服务的优先级设置的比普通应用要高,一个应用可以声明自己是foreground(调用startForeground())从而减少被系统杀掉后台的可能性.一般像社交软件或者播放器,肯定希望一直在后台播放或者收到消息时发送提醒,如果服务被系统干掉,那软件就达不到原来的目的.
Content Provider
这个是一种规范技术,一个应用可以向其他应用提供数据,通过实现Content Provider要求的接口,实现之后,其他应用可以通过访问在Content Provider中定义的URI来增删改查数据,这些数据可以通过文件或者SQLite数据库的方式来提供.
原生的安卓应用中,有很多标准的Content Provider应用,比如通讯录,电话等,向整个系统中的其他应用提供其中的数据.想要找到当前系统上的所有Content Provider,可以通过Content Resolver这个解析程序来查询.
其实这个也好理解,除了数据库之外,可能还有很多应用也有自己的数据,但是肯定不方便让其他应用直接去读写自己管理的数据库,但是这些数据又需要放开给别的应用使用,于是就让这个应用实现接口,变成一个符合要求的Content Provider.
Application Manifest
这个是一个XML文件,每个标准的安卓应用中都会包含这个文件,会把这个应用需要的所有元素和资源都写在这个文件里.一般会列出应用的Activity,服务,Broadcast Receiver,对外可提供哪些数据,权限等,包含了一个应用的各个方面的信息.在Android Studio中,一个应用下边被划分为manifests,java和res三大块,manifests对应的就是这个部分.
Application Resources
应用的资源文件一般是指的组成一个应用的所需的全部内容的非代码部分,一个安卓应用会有一个包(目录)存放其所需的所有资源文件的集合.一般包括长字符串文件,图片,字体,颜色文件,以XML文件定义的用户界面,在我们的开发中,res目录下边的就都是资源文件.
Application Context
在一个应用被编译完成之后,有一个叫做R的类会被创建,这个类指向当前应用的所有Application Resources.应用上下文就是由这个类加上manifest组成,用于在程序运行时访问所有的代码以外的资源,这个类是由Android包的Context类实现,上下文其实就是整个程序的环境,所以这个类有很多方法可以获取当前程序运行的环境,以及更改一些环境设置.提到上下文,只要搞过开发的肯定都明白是什么意思了.我读到这里也明白了为什么有一个R类了.
总结
一个安卓应用是由各个可重用,可替换的模块组成,这些模块就是上面提到的这些要素.在一个实际的应用中,一些模块是必须存在的(比如R类,Activity),还有一些是可选的,即不一定要实现该功能.学习安卓开发,其实也就是学习各个模块的编写方法.