Android系统架构
- 平台架构
- Linux内核层(Linux Kerenl)
- Android系统是基于Linux内核的,这一层为Android设备的各种硬件提供了底层的驱动,如显示驱动、音频驱动、照相机驱动、蓝牙驱动、Wi-Fi驱动、电源管理等。
- 硬件抽象层 (HAL)
- 硬件抽象层 (HAL)提供标准界面,向更高级别的Java API 框架显示设备硬件功能。HAL 包含多个库模块,其中每个模块都为特定类型的硬件组件实现一个界面,例如相机或蓝牙模块。当框架 API 要求访问设备硬件时,Android 系统将为该硬件组件加载库模块
- 系统运行库层
- Native C/C++ Libraries
- 这一层通过一些C/C++库来为Android系统提供了主要的特性支持。如SQLite库提供了数据库的支持,OpenGL|ES库提供了3D绘图的支持,Webkit库提供了浏览器内核的支持等
- .so文件都是来自于这一层
- Android Runtime
- 这一层还有Android运行时库,它主要提供了一些核心库,能够允许开发者使用Java语言来编写Android应用。
- Android运行时库中还包含了Dalvik虚拟机(5.0系统之后改为ART运行环境),它使得每一个Android应用都能运行在独立的进程当中,并且拥有一个自己的Dalvik虚拟机实例。
- 相较于Java虚拟机,Dalvik是专门为移动设备定制的,它针对手机内存、CPU性能有限等情况做了优化处理。
- Native C/C++ Libraries
- 应用框架层(Java API Framework)
- 这一层是整个安装开发的重点,四大组件都是在这一层(Activiy(界面)、service(服务)、content provider(内容)、broadcast receiver(广播)),主要提供了构建应用程序时可能用到的各种API,Android自带的一些核心应用就是使用这些API完成的,开发者也可以通过使用这些API来构建自己的应用程序
- 应用层(System Apps)
- 所有安装在手机上的应用程序都是属于这一层的,比如系统自带的联系人、短信等程序,或者是你从Google Play上下载的小游戏,当然还包括你自己开发的程序
- Linux内核层(Linux Kerenl)
Android 是一种基于 Linux 的开放源代码软件栈,为各类设备和机型而创建。下图所示为 Android 平台的主要组件。
Android应用开发特色
- Android四大组件
- 活动(Activity)
- 服务(Service)
- 广播接收器(Broadcast Receiver)
- 内容提供器(Content Provider)
- Android六大布局
- 线性布局(LinearLayout) 按照垂直或者水平方向布局的组件
- 帧布局(FrameLayout) 组件从屏幕左上方布局组件
- 表格布局(TableLayout) 按照行列方式布局组件
- 绝对布局(AbsoluteLayout) 按照绝对坐标来布局组件
- 相对布局(RelativeLayout) 相对其它组件的布局方式
- 约束布局 (ConstraintLayout) 按照约束布局组件
- Android五大存储
- 文件存储(通过JavaIO流的读写方法写入到文件中)
- SharePreferences(以键值对形式存储在xml中)
- SQLite(嵌入式关系型数据库,使用SQL语言)
- ContentProvider(作为传输数据的媒介,数据源可多样性)
- 网络存储(通过网络获取远程服务器的数据)
搭建开发环境
- Android程序开发工具
- JDK
- JDK是Java语言的软件开发工具包,它包含了Java的运行环境、工具集合、基础类库等内容
- Android SDK
- Android SDK是谷歌提供的Android开发工具包,在开发Android程序时,我们需要通过引入该工具包,来使用Android相关的API
- JDK
- IDE
- Android Studio
- 将所有需要用到的开发工具都集成好了(自Android Studio 2.2.1 开始已经内置OpenJDK 8)
- Android Studio 版本 4.1.2
- Android SDK 5.0(API 21)
- 修改 build.gradle 文件
compileSdkVersion 30buildToolsVersion "30.0.0"targetSdkVersion 30
- Android Studio
- 真机调试
- 打开开发者模式
- 开启USB调试(小米手机还需开启USB安装)
- adb
- adb是Android SDK中自带的一个调试工具,使用这个工具可以直接对连接在电脑上的手机或模拟器进行调试操作
- 它存放在sdk的platform-tools目录下,如果想要在命令行中使用这个工具,就需要先把它的路径配置到环境变量里
- Windows系统,可以右击计算机→属性→高级系统设置→环境变量,然后在系统变量里找到Path并点击编辑,将platform-tools目录配置进去
目录结构
- 目录结构
- Android 模式 - 按项目区分
- Project 模式 - 按文件夹区分
- app模块 - 模块的整体配置、构建文件以及模块级别的设置
- build - 包含构建过程生成的文件,包括APK文件、临时文件等
- libs - 模块使用到了第三方jar包
- src - 模块的源代码和资源文件
- androidTest - 用于编写 Android 测试代码
- main
- java - Java 源代码文件
- res - 资源文件
- 图片放在drawable目录下
- 布局放在layout目录下
- 常量(颜色、字符串、主题)放在values目录下
- mipmap图标目录(适配不同分辨率)
- AndroidManifest.xml - 模块的配置文件
- test - 用于编写单元测试
- .gitignore - 定义模块的git忽略文件
- build.gradle - 定义模块的构建设置,包括编译配置和依赖关系
- proguard-rules.pro - 定义了 Proguard 的规则,用于混淆和优化代码
- gradle - 包含Gradle的配置和脚本
- wrapper - 包含 Gradle Wrapper 文件,用于自动下载和使用指定版本的 Gradle
- .gitignore - git忽略文件
- build.gradle - 定义项目的全局构建配置,包括构建脚本的依赖和仓库
- gradle.properties - 全局gradle的配置文件
- gradlew - 在Linux或Mac系统中命令行界面中执行 Gradle 命令
- gradlew.bat - 在Windows系统中命令行界面中执行 Gradle 命令
- local.properties - 指定本地环境相关的配置信息,Android SDK 的路径等
- settings.gradle - 定义项目的模块和其他配置
- app模块 - 模块的整体配置、构建文件以及模块级别的设置
活动(Activity)
Android权限机制
- Android运行时权限(6.0系统)
- 分类
- 普通权限
- 普通权限指的是那些不会直接威胁到用户的安全和隐私的权限,对于这部分权限申请,系统会自动帮我们进行授权,而不需要用户再去手动操作
- 危险权限
- 危险权限则表示那些可能会触及用户隐私或者对设备安全性造成影响的权限,如获取设备联系人信息、定位设备的地理位置等,对于这部分权限申请,必须要由用户手动点击授权才可以,否则程序就无法使用相应的功能
- 特殊权限
- 普通权限
- Android系统中完整的权限列表
- 开发流程
- AndroidManifest.xml 添加权限
- 先判断用户是不是授权,借助的是ContextCompat.checkSelfPermission()方法
- 使用方法的返回值和PackageManager.PERMISSION_GRANTED做比较,相等就说明用户已经授权,不等就表示用户没有授权
- 如果没有授权的话,则需要调用ActivityCompat.requestPermissions()方法来向用户申请授权
- 调用完了requestPermissions()方法之后,系统会弹出一个权限申请的对话框,然后用户可以选择同意或拒绝我们的权限申请,不论是哪种结果,最终都会回调到onRequest-PermissionsResult()方法中,而授权的结果则会封装在grantResults参数当中。这里我们只需要判断一下最后的授权结果
内容提供器
- 简介
- 使用内容提供器是Android实现跨程序共享数据的标准方式,允许一个程序访问另一个程序中的数据
- 如果一个应用程序通过内容提供器对其数据提供了外部访问接口,那么任何其他的应用程序就都可以对这部分数据进行访问
- 用法
- 一种是使用现有的内容提供器来读取和操作相应程序中的数据
- 一种是创建自己的内容提供器给我们程序的数据提供外部访问接口
- 通过内容提供器获取数据
- 借助Content-Resolver类,可以通过Context中的getContentResolver()方法获取到该类的实例
- Content-Resolver中提供了一系列的方法用于对数据进行CRUD操作
- insert()方法用于添加数据,update()方法用于更新数据,delete()方法用于删除数据,query()方法用于查询数据
- 内容uri(参数)
- 组成
- 内容URI给内容提供器中的数据建立了唯一标识符,它主要由两部分组成:authority和path
- authority 采用程序包名的方式来进行命名
- path则是用于对同一应用程序中不同的表
- 以路径结尾就表示期望访问该表中所有的数据,以id结尾就表示期望访问该表中拥有相应id的数据
*:表示匹配任意长度的任意字符#:表示匹配任意长度的数字
- 协议声明 + authority + path + 数据
- 组成
- Uri对象
- 将内容URI字符串解析成Uri对象才可以作为参数传入
- ContactsContract.CommonData-Kinds.Phone类已经帮我们做好了封装,提供了一个CONTENT_URI常量,而这个常量就是使用Uri.parse()方法解析出来的结果
- 内容uri(参数)
- insert()方法用于添加数据,update()方法用于更新数据,delete()方法用于删除数据,query()方法用于查询数据
- 创建内容提供器
com.example.包→New→Other→Content Provider- 内容提供器一定要在AndroidManifest.xml文件中注册才可以使用
- 通过新建类去继承ContentProvider的方式来创建内容提供器
- ContentProvider类中有6个抽象方法,用子类继承需要将这6个方法全部重写
- onCreate() - 初始化内容提供器的时候调用
- query() - 从内容提供器中查询数据
- insert() - 向内容提供器中添加一条数据
- update() - 更新内容提供器中已有的数据
- delete() - 从内容提供器中删除数据
- getType() - 根据传入的内容URI来返回相应的MIME类型
- 一个内容URI所对应的MIME字符串主要由3部分组成,Android对这3个部分做了如下格式规定
- 必须以vnd开头
- 如果内容URI以路径结尾,则后接android.cursor.dir/,如果内容URI以id结尾,则后接android.cursor.item/
- 最后接上vnd..
- 例子
content://com.example.app.provider/table1vnd.android.cursor.dir/vnd.com.example.app.provider.table1
- 一个内容URI所对应的MIME字符串主要由3部分组成,Android对这3个部分做了如下格式规定
- ContentProvider类中有6个抽象方法,用子类继承需要将这6个方法全部重写
- 匹配内容URI
- 借助UriMatcher这个类,UriMatcher中提供了一个addURI()方法,这个方法接收3个参数,可以分别把authority、path和一个自定义代码传进去
- 当调用UriMatcher的match()方法时,就可以将一个Uri对象传入,返回值是某个能够匹配这个Uri对象所对应的自定义代码,利用这个代码,就可以判断出调用方期望访问的是哪张表中的数据了
多媒体
-
通知
- 使用一个Builder构造器来创建Notification对象
- 需要一个NotificationManager来对通知进行管理
- 需要调用NotificationManager的notify()方法就可以让通知显示出来
- PendingIntent
- 用于启动活动、启动服务以及发送广播等
-
摄像头和相册
- 在 Android 6.0(API级别23)及更高版本中,应用在运行时需要请求敏感权限
-
播放自媒体
网络技术
- WebView
- 可以在自己的应用程序里嵌入一个浏览器
- 使用HTTP协议访问网络
- HttpClient(6.0废弃)
- HttpURLConnection
- OkHttp
- 在清单文件中配置网络安全策略
- 搭建服务器
- 解析 xml
- Pull解析方式
- SAX解析方式
- 用法比Pull解析要复杂一些,但在语义方面会更加清楚
- DOM解析方式
- 解析 JSON
- JSONObject
- GSON
- 可以将一段JSON格式的字符串自动映射成一个对象,从而不需要手动去编写代码进行解析
- Jackson
服务
- 简介
- Android中实现程序后台运行的解决方案
- 需要在服务的内部手动创建子线程,并在这里执行具体的任务
- Android多线程编程