Android chapter1


第一行代码读书笔记

简介

Android系统架构

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

  1. Linux内核层

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

  1. 系统运行库层

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

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

  1. 应用框架层

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

  1. 应用层

所有安装在手机上的应用都是属于这一层的,比如系统自带的联系人、短信等程序,也包括你自己开发的程序。

Android已发布的版本

  • 2011年2月,谷歌发布了 Android 3.0系统,是专门为平板电脑设计的,但也是 Android 位数不多的比较失败的版本。

  • 2011年10月,谷歌发布了 Android 4.0系统,这个版本不再对手机和平板进行差异化区分。

  • 2015年 Google I/O 大会上推出了号称史上版本改动最大的 Android 5.0 系统,其中使用了 ART 运行环境替代了 Dalvik 虚拟机,大大提升了应用的运行速度,还提出了 Material Design 的概念来优化应用的界面设计。除此之外,还推出了 Android Wear、Android Auto、Android TV 系统,从而进军可穿戴设备、汽车、电视等全新领域。

  • 2015年 Google I/O 大会上推出了 Android 6.0系统,加入运行时权限功能。

  • 2016年 Google I/O 大会上推出了 Android 7.0系统,加入多窗口模式功能。

Android应用开发特色

  1. 四大组件

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

  1. 丰富的系统控件

Android 系统为开发者提供了丰富的系统控件,使得我们可以很轻松地编写出漂亮的界面。当如如果你品位高,不满足于系统自带的控件效果,也完全可以定制属于自己的控件。

  1. SQLite数据库

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

  1. 强大的多媒体

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

  1. 地址位置定位

移动设备和 PC 相比起来,地理位置定位功能应该可以算术很大的一个亮点。现在的 Android 手机都内置有 GPS,走到哪儿都可以定位到自己的位置,发挥你的想象既可以做出创意十足的应用,如果再结合功能强大的地图功能,LBS 这一领域潜力无限。

环境搭建

需要准备的工具

  • JDK。JDK是 Java 语言的软件开发工具包,它包含了 Java 的运行环境、工具集合、基础类库等内容。

  • Android SDK。Android SDK 是谷歌提供的 Android 开发工具包,在开发 Android 程序时,我们需要通过引入该工具包,来使用 Android 相关的 API。

  • Android Studio。在很早之前,Android 项目都是用 Eclipse 来开发的,相信所有 Java 开发者都一定会对这个工具非常熟悉,它是 Java 开发神器,安装 ADT 插件后就可以用来开发 Android 程序了。而在 2013 年的时候,谷歌推出了一款官方的 IDE 工具 Android Studio,由于不再是以插件的形式存在,Android Studio 在开发 Android 程序方面远比 Eclipse 强大和方便得多。

搭建开发环境

上述软件我们并不需要一个一个的进行安装,谷歌为了简化搭建开发环境的过程,将大量需要用到的工具都帮我们集成好了,到 Android 官网就可以下载最新的开发工具 Android Studio,下载地址是:

在安装 Android Studio 之前,我们需要先安装 JDK,因为 Android Studio 和 Android 应用开发都依赖于 Java。安装完 JDK 后,我们再安装 Android Studio,安装过程中可以选择安装 SDK。

安装完 JDK 和 Android Studio后我们也就搭建好了基本的开发环境。

项目创建

创建第一个项目

目前,大量 Android 程序采用 Kotlin 开发。相比 Java,Kotlin 在 Android 开发中更为强大,但严格来说它是 Java 的超集,具备与 Java 的高度兼容性。因此,在学习 Kotlin 之前,掌握 Java 基础是必要的。

  1. 在最新的 Android Studio 中创建 Java 项目。

选择 new project新建一个Java项目,然后选择No Activity,给项目起一个名称为Hello World

其中Package name表示项目的包名,然后选择Finish即可。

  1. APP目录结构
  • manifests

这个目录用于存放AndroidManifest.xml文件,AndroidManifest.xml文件是整个项目的配置文件,程序中定义的所有四大组件都需要在这个文件里注册。

  • java

Java目录是防止我们所有代码的地方。

  • res

项目中使用到的所有图片、布局、字符串等资源都要存放在这个目录下。当然这个目录下还有许多子目录,图片放在drawable目录下,布局放在layout目录下,字符串放在values目录下。

  1. 给项目创建Activity

右击项目中的com.example.helloworld,选择New,然后选择Activity,最后选择Empty Views Activity

之后com.example.helloworld下就会多一个MainActivity,接下来我们需要修改activity_main.xmlAndroidMaiifest.xml文件。

activity_main.xml文件位于res/layout文件夹中,用于定义主界面的布局。它描述了界面上的 UI 元素(如按钮、文本视图等)以及它们的排列方式,是在运行时展现给用户的界面内容。
AndroidManifest.xml是应用的配置文件,定义了应用的基本信息(如包名、应用组件、权限等)。它位于mainifests目录下,告诉系统应用包含的组件以及如何与系统和其他应用交互。

找到activity_main.xml文件,然后点击右上角的CODE,然后添加以下代码。

下面这段xml代码定义了一个TextView控件,它使用ConstraintLayout的约束方式,将控件居中于父布局中。

1
2
3
4
5
6
7
8
9
10
<TextView  
android:id="@+id/helloTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, World!"
android:textSize="24sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>

我们用它来显示Hello World!

之后我们再修改AndroidManifest.xml文件,插入下面的代码。

下面的代码表示对MainActivity这个活动进行注册,没有在AndroidManifest.xml里注册的活动是不能使用的。

下面代码中的android.intent.action.MAINandroid.intent.category.LAUNCHER表示MainActivity是这个项目的主活动,在手机上点击应用图标,首先启动的就是这个活动。

1
2
3
4
5
6
7
8
<activity  
android:name="com.example.helloworld.MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

接下来我们分析一下MainActivity这个主活动的代码

1
2
3
4
5
6
7
8
9
10
public class MainActivity extends AppCompatActivity {  

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EdgeToEdge.enable(this);
setContentView(R.layout.activity_main);
});
}
}

首先可以看到MainActivity是继承自AppCompatActivity的,这是一种向下兼容的ActivityActivityAndroid系统提供的一个活动基类,我们项目中的所有活动都必须继承它或者它的子类才能拥有活动的特性(AppCompatActivityActivity的子类)。然后可以看到,MainActivity中有一个onCreate()方法,这个方法是一个活动被创建时必定要执行的方法,其中只有两行代码,并没有Hello World!

因为Android程序的设计讲究逻辑和视图分离,因此是不直接在活动中直接编写界面的,更加通用的方法是在布局文件中编写界面,然后在活动中引入进来,可以看到,在onCreate方法的第二行调用了setContentView()方法,就是这个方法给当前的活动引入了一个activity_main的布局。

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

这个文件中有一个我们上面插入的TextView,这是Android系统提供的一个控件,用于在布局中显示文字的。

详解项目中的资源

res目录

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

程序中一般会有很多mipmap开头的文件夹,起始主要是为了让程序能够更好地兼容各种设备。

知道了res目录下每个文件夹的含义,我们来看一下如何去使用这些资源。

打开res/values/strings.xml文件,内容如下所示:

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

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

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

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

下面举一个简单的例子来帮助理解,打开AndroidManifest.xml文件,查看。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<application        android:allowBackup="true"  
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.HelloWorld"
tools:targetApi="31">
<activity android:name="com.example.helloworld.MainActivity"
android:exported="true">
<intent-filter> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

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

启动模拟器运行

但是我们使用电脑开发并无法直接运行 Android程序,Android程序是要运行在Android系统上的,Android Studio提供了内置模拟器,我们可以通过模拟器运行 Android 程序。

创建模拟器后我们只需要点击右上角的运行,既可运行Android程序。

日志工具的使用

使用Android的日志工具Log

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

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

起始很简单,一共就 5 个方法,当然每个方法还会有不同的重载,但那对你来说

为什么使用Log而不使用System.out

为什么在Android中会偏向于使用Log而不是使用System.out.println,这是因为LogSystem.out相比,可以控制日志打印、可以设定打印时间、可以添加过滤器,并且对日志有所区分比如Eroor信息和Debug信息,总结就是功能更加强大。

我们可以通过快捷输入的方式在Android Studio中快速使用Log,比如在代码中输入logd然后按tab补全会自动补全一条完整的打印语句,同理输入logi对应info级别的日志,logw对应warn级别的日志,以此类推。

另外,由于Log的所有方法都要求传入一个tag参数,每次写一遍显然太过麻烦,我们可以在onCreate()方法的外面输入logt,然后按下tab键,这时就会以当前的类名作为值自动生成一个tag常量。

除了快捷输入之外,logcat中还能很轻松地添加过滤器。