本系列学习笔记第1章
前言
打算把android基本知识点写一个系列,旨在把android基础书,例如《Android 第一行代码 第2版》、《爱上android》、《疯狂android讲义》等书的一些知识点记录一下,会持续更新内容,为了方便自己复习,也希望可以帮助到大家!
1、 Android王国简介
1.1 Android系统架构
Android的系统架构大致可以分为四层,如图所示:
![](https://img.haomeiwen.com/i2108792/ede69138186b2bd7.png)
1) Linux内核层
android系统基于Linux内核的,这一层是android最底层最核心的部分,这一层为android设备的各种硬件提供了底层驱动,如显示、音频、照相机、蓝牙、Wi-Fi、电源管理驱动等。
2)系统运行库层
这一层有一些C/C++库来提供一些主要的特性支持,如SQLite库提供数据库支持、OpenGL | OpenES库提供3D绘图的支持,Webkit库提供了浏览器内核的支持。这一层还有Android运行时库,它包括了Dalvik虚拟机(每个App都会分配Dalvik虚拟机来保证相互之间不受干扰,并且保持独立,它的特点是在运行时编译,就比如你买了一辆可折叠的自行车,平时是折叠的,只有骑的时候,才需要组装起来用),5.0之后的系统改为ART运行环境(安装时就进行编译,以后运行时就不用编译了,就好比你买了俩组装好的自行车,转好就可以骑了),它使得Android应用都能运行在独立的进程当中,并且拥有一个自己的虚拟机实例。
3)应用框架层(Framework)
主要为开发者构建应用程序时可能用到的各种API。
2)应用层
所有安装在手机上的应用程序都是属于这一层的。
1.2 Android App组件架构
在应用层,Android App组件架构,通常是Android的四大组件:Activity、BroadCaseReceiver、ContentProvider、Service,她们是组成一个Android App的最基本元素。
1)Android 四大组件如何协同工作
Android中的四大组件的使用方法和适用场景都各不相同,但是它们也保持着紧密的联系,你中有我,我中有你,紧密而不可分。
Activity:人机交互的第一界面,负责向用户展示信息和处理结果
Content Provider:作为信息的来源之一,可以获取其它应用的信息
Service:作为信息的来源之一,从后台计算、下载、处理的结果
Content Provider:作为信息的来源之一,可以获取广播的信息
Intent:Android系统提供的信使,作为信息传递的载体,组件与组件之间通过Intent来通信、传递信息、交互数据
正是通过这样的一种方式,四大组件形成了各组独立而又紧密联系的关系,让Android系统 活起来
2)应用运行上下文对象
在程序中,我们可以理解为当前对象在程序中所处的一个环境,一个与系统交互的过程。
Android系统的上下文对象,即在Context中,为我们封装了这样一个”语境“。Activity、Service、Application都是继承自Context。
Android应用程序会在如下所示的几个时间点创建应用上下文Context:(创建Context的时机就是在创建Context的实现类的时候)
- 创建Application(贯穿整个引用进程的生命周期,为应用全局提供了功能和环境支持)
- 创建Activity(组件上下文,通过this或者XXXActivity.this来获取)
- 创建Service(组件上下文,通过this来获取)
1.4 Android系统源代码目录
查看Android源代码的网站:http://androidxref.com/
![](https://img.haomeiwen.com/i2108792/81875588cb34cd9c.png)
![](https://img.haomeiwen.com/i2108792/6574b63182e9c174.png)
AOSP的Android项目结构:
- Makefile
- bionic (bionic C库)
- bootable (启动引动相关代码)
- build (存放系统编译规则等基础开发配置)
- cts(Google兼容性测试标准)
- dalvik(dalvik 虚拟机)
- developers(应用程序开发相关)
- external (android使用的一些开源模块)
- frameworks(Framework框架核心)
- hardware(厂商硬件适配层HAL代码)
- packages(应用程序包)
- out(编译完成后的代码输出目录)
- prebuilts(x86和arm架构下预编译资源)
- sdk(sdk及模拟器)
- system(底层文件系统库、应用及组件)
- vendor(厂商定制代码)
Makefile机制:
一个像Android这样的大工程,源文件不计其数,不同的功能、模块、按类型分别放置在不同的目录中,这些模块通常会有一个叫Makefile的文件来进行管理,它定义了一系列的故则来指定模块,哪些文件需要编译,以及这些文件该按照怎么样的顺序去编译,甚至它还可以配置更复杂的功能操作,比如定义编译规则、打包附则等,因为Makefile就像一个shell脚本,不仅可以使用自己的语法,也能调用操作系统的命令。
可以看到Makefile最大的好处就是自动化编译,同时还可以做到可控制编译,Android通过Makefile来描述Android各个组件间的联系并且指导他们进行自动化编译。Makefile的语法,指定了各个源代码该如何连接并且生成相应的可执行程序。上面的目录结构,每个目录下会包含更多的目录,而它的每个最小的功能单位目录下都会有一个Makefile文件,这样每一级向上,通过这样一个个Makefile文件,就把整个源代码有条不乱联系在一起。
1.5 Android系统目录
手机的Android系统目录与源代码目录并不是一一对应的,而是与源代码编译之后,与打包生成的Image文件的结构相同
![](https://img.haomeiwen.com/i2108792/46809d67f6b242de.png)
![](https://img.haomeiwen.com/i2108792/7ec6ed0b7d2b6cb3.png)
对开发者来说,最重要的就是/system 和 /data 这俩个目录
-
/system/app/ (系统中的App)
image.png
-
/system/bin/ (主要存放的是Linux自带的组件)
image.png
-
/system/build.prop (系统的属性信息)
image.png
-
/system/fonts/ (系统的字体存放的目录)
-
/system/framework/ (系统的核心文件、框架层)
-
/system/lib/ (共享库)
-
/system/media/ (保存系统提示音、系统铃声)
image.png
-
/system/usr/ ( 保存用户配置文件,如键盘布局、共享、时区文件等)
-
/data/app/ ( 用户的大部分数据信息)
-
/data/data/ ( 以包名区分各个应用)
-
/data/system/ (手机的各项系统信息)
-
/data/misc/ (wi-fi vpn信息)
1.6 Android各版本一览表
![](https://img.haomeiwen.com/i2108792/37dcaaa81a41eedb.png)
目前4.0以上的系统已经占据超过了98%的android应用市场,因此开发只要兼容4.0以上应该就差不多了。
2、 开发环境搭建
在网上找一下,或者请看我之前重装系统时重新搭建android开发环境写的一篇博文
https://www.jianshu.com/p/7a8556f0b4f9
Android Studio 官网下载地址:
https://developer.android.com/studio/
国内镜像网站:
http://www.androiddevtools.cn/
3、 项目结构模式以及目录文件
3.1 项目结构模式
点击图上所示,就可以看到项目的结构模式,一般常用的有Android 以及 Project这俩种
![](https://img.haomeiwen.com/i2108792/d7b7404ea0f46941.png)
3.2 项目最外层目录
![](https://img.haomeiwen.com/i2108792/dd32368d74760c61.png)
1).gradle 和.idea
Android Studio自动生成的
2)build
Android Studio 项目编译时自动生成的文件
3)app
开发中的代码、资源都在这里
4)gradle
里面的gradle.wrapper配置文件,会根据Android Studio的设置来决定是否联网下载或者使用离线的
![](https://img.haomeiwen.com/i2108792/ec9bd48bc4718445.png)
![](https://img.haomeiwen.com/i2108792/b31d410b792fdfb5.png)
5).gitignore
指定版本控制时要忽略的文件
6)build.gradle
项目全局的gradle构建脚本,Android Studio 是采用Gradle来构建项目的。
![](https://img.haomeiwen.com/i2108792/40ffc40e359a09e0.png)
7)gradle.properties
全局的gradle配置文件,如果电脑性能不好,嫌弃项目编译速度慢的话,可以更改这里的配置
![](https://img.haomeiwen.com/i2108792/d1ee35bd8b313004.png)
8)gradlew和gradlew.bat
用了即行gradle命令的,前者是在Linux或者Mac系统中使用,后者是在Windows系统中使用
9)xxx.iml
这个是Android Studio自动生成的,标识这是一个IntelliJ IDEA项目
10)local.properties
指定Android SDK路径
![](https://img.haomeiwen.com/i2108792/c652ad38221a1788.png)
11)settings.gradle
用于指定项目中所有引入的模块
![](https://img.haomeiwen.com/i2108792/b2508dca80af407a.png)
3.3 项目app模块最内层目录
![](https://img.haomeiwen.com/i2108792/303535cd12923a70.png)
1)build
和外层的build目录类似,都是在编译时Andrid Studio自动生成的文件
2)libs
第三方jar包放置的地方
3)androidTest
用来编写Android Test测试用例的,可以对项目进行一些自动化测试
4)java
所有编写java代码的地方
5)res
项目中使用的所有图片、布局、字符串等资源存储的地方
![](https://img.haomeiwen.com/i2108792/b138d5bd4a70e9c1.png)
6)AndroidManifest.xml
程序中所有的4大组件以及应用权限声明都在这里
![](https://img.haomeiwen.com/i2108792/1325b22b5228460c.png)
7)test
用来编写Unit Test测试用例的,是对项目进行自动化测试的另一种方式
8)版本控制忽略文件,跟外层的一样
9) app.iml
项目自动生成的文件
10)build.gradle
app模块的gradle构建脚本
![](https://img.haomeiwen.com/i2108792/950cf042e693f06a.png)
![](https://img.haomeiwen.com/i2108792/39bc835fc750e7f9.png)
![](https://img.haomeiwen.com/i2108792/8404ded1e71ac2d5.png)
11)proguard-rules.pro
用于指定项目代码的混淆规则
4、 Android的日志工具Log
![](https://img.haomeiwen.com/i2108792/76f027d838d1c633.png)
-
Log.v() 对应级别verbose,是Android日志里面级别最低的一种,主要打印那些最为琐碎的、意义最小的日记信息
-
Log.d() 对应级别debug,比verbose高一级,主要打印一些调试信息
-
Log.i() 对应级别info,比debug高一级,主要打印一些比较重要的数据信息
-
Log.w() 对应级别warn,比info高一级,主要打印一些警告信息
-
Log.e() 对应级别error,比warn高一级,主要打印程序中的错误信息
![](https://img.haomeiwen.com/i2108792/ca48aeee4798aa42.png)
5、 buildTypes 在实际项目中的使用
//构建类型:可以根据不同的版本设置不同的参数,进行不同的配置
buildTypes {
debug{
minifyEnabled false
buildConfigField "String","API_URL","\"https://yuedu.baidu.com\""
buildConfigField "boolean","LOG_CALLS","true"
resValue "string","str_name","Example DEBUGLE"
}
release {
minifyEnabled true
buildConfigField "String","API_URL","\"https://yuedu.baidu.com\""
buildConfigField "boolean","LOG_CALLS","false"
resValue "string","str_name","example"
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
![](https://img.haomeiwen.com/i2108792/eb640dba4b9e99e5.png)
在代码中可以引用自己上图中定义的一些参数,调用如下:
String url = BuildConfig.API_URL;
boolean logCalls = BuildConfig.LOG_CALLS;
int str_name = R.string.app_name;
在LogUtils工具类中的引用:
public class LogUtils {
public static final boolean DEBUG = BuildConfig.LOG_CALLS;
public static void v(String tag,String msg){
if(DEBUG) {
Log.v(tag, msg);
}
}
public static void d(String tag,String msg){
if(DEBUG) {
Log.d(tag, msg);
}
}
public static void i(String tag,String msg){
if(DEBUG) {
Log.i(tag, msg);
}
}
public static void w(String tag,String msg){
if(DEBUG) {
Log.w(tag, msg);
}
}
public static void e(String tag,String msg){
if(DEBUG) {
Log.e(tag, msg);
}
}
}
6、 屏蔽日志输出的终极做法
在混淆文件中对Log的输出添加如下所示的混淆:
-assumenosideeffects class android.util.Log {
public static boolean isLoggable(java.lang.String,int);
public static *** d(...);
public static *** v(...);
public static *** i(...);
public static *** w(...);
public static *** e(...);
}
对于assumenosideeffects ,官方的解释就是,混淆器将删除这些方法(如果在程序中使用这些方法的返回值,则不会删除,一般日志不关心返回值)。)
对于build.gradle和日志输出这一块,推荐观看我之前写的博文:
https://www.jianshu.com/p/2febe846f11c
网友评论