首页文章【Android】系统框架-第一行代码启程!

【Android】系统框架-第一行代码启程!

时间2025-04-23 10:01:38发布yu分类文章浏览7
导读:这一层装配了一个核心应用程序,包括浏览器、联系人、电话、日历、相机等应用;除此之外,用户开发的Android应用也处于这一层,比如微博、微信、QQ等;...
  • 这一层装配了一个核心应用程序,包括浏览器、联系人、电话、日历、相机等应用;
  • 除此之外,用户开发的Android应用也处于这一层,比如微博、微信、QQ等;
  • 总的来说,应用程序层包括了所有的Android应用程序,其可以分为系统自带的核心应用程序以及用户自行开发的应用程序。

它提供了大量可供开发人员使用的应用程序接口(Application Programming Interface,API),Android自带的很多核心应用也是使用这些API完成的。

  • 应用程序框架层主要提供的组件如下表所示:

  • 位置管理器 Location Manager 提供地理位置及定位功能服务

  • 包管理器 Package Manager
    管理所有安装在Android系统中的应用程序

  • 通知管理器 Notification Manager
    使应用程序可以在状态栏中显示自定义的提示信息

  • 资源管理器 Resource Manager
    提供应用程序使用的各种非代码资源,如本地字符串、图片、布局文件、颜色文件等

  • 电话管理器 Telephony Manager

  • 管理所有的移动设备功能

  • 窗口管理器 Window Manager
    管理所有开启的窗口程序

  • 内容提供者 Content Provider
    使不同应用程序之间可以共享数据

  • 视图系统 ViewSystem
    丰富的、可扩展的视图,可用于构建一个应用程序,包括列表(Lists)、网格(Grids)、文本框(TextBoxes)、按钮(Buttons),甚至是内嵌的Web浏览器

应用程序框架层集中了很多Android开发需要的组件,其中最主要的就是Activities(活动)、Broadcast Receiver(广播接收器)、Services(服务)以及Content Providers(内容提供者)这四大组件。

系统库

  • Android包含一些原生C/C++库,这些库能够被安卓系统的不同组件使用。它们通过Android应用框架为开发者提供服务。
  • 开发者可以通过调用Java API Framework来使用原生库的功能,也可以用Android NDK直接调用原生库。
  • 系统库包括九个子系统,分别是:
系统C语言库标准C语言系统库 (libc) 的 BSD 衍生,调整为基于嵌入式 Linux 设备多媒体库基于 PacketVideo 的 OpenCORE,这些库支持播放和录制许多流行的音频和视频格式,以及静态图像文件,包括 MPEG4、H.264、MP3、AAC、AMR、JPG、PNG图层管理(Surface Manager)对显示子系统的管理,并且为多个应用程序提供 2D 和 3D 图层的无缝融合SQLite轻量级关系数据库引擎3D库基于OpenFLES1.0 APLs实现,该库可以使用硬件3D加速或者使用高度优化3D软加速FreeType位图与矢量字体显示渲染LibWebCore新式的 Web 浏览器引擎,支持 Android 浏览器和内嵌的 Web 视图SGL内置的2D图形引擎SSL支持数据通信

Android运行时

Dalvik虚拟机(在Android 5.0之前):一种专为移动设备优化的Java虚拟机。

ART(Android Runtime)**(在Android 5.0及之后):替代Dalvik虚拟机,提供更好的性能和垃圾回收机制。

  • Android运行时包括核心库以及Dalvik虚拟机(Android 5.0以后更改为ART虚拟机)。
  • 前者既兼容了大多数Java语言所需要的功能函数,又包括了Android的核心库,比如android.os、http://android.net、android.media等。
  • 后者是一种基于寄存器的Java虚拟机,每一个Android应用都运行在单独的进程中,拥有一个独立的Dalvik虚拟机实例。
Dalvik虚拟机概述
  • Google为Android平台专门设计的一套虚拟机来运行Android应用程序,那就是Dalvik虚拟机(Dalvik Virtual Machine,DVM)。 注意:尽管Android应用程序是通过Java语言来开发的,但其并不是运行在标准的Java虚拟机上。

DalVik虚拟机作为Android平台的核心组件,拥有如下特点: 1. 体积小,占用内存空间小; 2. 执行专有的DEX(Dalvik Executable)文件格式,体积更小,执行速度更快; 3. 常量池采用32位索引值,寻址类方法名、字段名、常量更快; 4. 基于寄存器架构,并拥有一套完整的指令系统; 5. 提供对生命周期的管理、堆栈的管理、线程的管理、安全和异常的管理以及垃圾回收等重要功能; 6. 所有Android应用程序都运行在Android系统进程里,每个进程对于一个Dalvik虚拟机实例。

  • Dalvik虚拟机采用的是JIT(Just-in-time Compilation,即时编译)技术,在运行应用时将字节码翻译为机器码,从而使程序的执行速度更快。但随着硬件水平的不断发展以及人们对更高性能的需求,Dalvik虚拟机的不足日益突出。
  • Google在2014年推出了新的虚拟机ART,并从Android5.0开始废弃了Dalvik,全面推行ART。ART虚拟机采用AOT(Ahead-of-time)技术,在应用程序安装时就会将字节码转换为机器码,从而优化了应用运行的速度。在内存管理方面,ART也有比较大的改进,对内存分配和回收都做了算法优化,降低了内存碎片化程度,回收时间也得以缩短。
Dalvik虚拟机与Java虚拟机的区别
Dalvik虚拟机Java虚拟机虚拟机架构基于寄存器架构,数据访问通过寄存器间直接传递,编译和运行都会更快一些基于栈架构,编译和运行会慢一些字节码执行.dex格式的Dalvik字节码,由.class文件通过Android SDK目录下名为dx的工具压缩后产生的,体积更小执行.class格式的Java字节码运行环境一个应用启动会运行一个单独的虚拟机,运行在独立的进程中所有应用都运行在同一个虚拟机中
  • 硬件抽象层处于应用程序框架层和Linux内核驱动之间,用于将硬件抽象化。简单来说,就是对内核驱动程序进行封装,向上提供接口,向下屏蔽具体实现细节。
  • 系统抽象层包含多个库模块,每个模块都为特定类型的硬件组件实现接口,例如相机、蓝牙模块。
  • 当应用程序框架层API要访问设备硬件时,Android系统会为该硬件组件加载库模块。
  • Android基于Linux提供核心系统服务,例如安全、内存管理、进程管理、网络堆栈、驱动模型。
  • 除了标准的 Linux 内核外,Android 还增加了内核的驱动程序,如Binder(IPC)驱动、显示驱动、输入设备驱动、音频系统驱动、摄像头驱动、WiFi驱动、蓝牙驱动、电源管理。

1. Activity(活动)

Activity是Android应用程序的门面,主要用于构建应用的用户界面。每个Activity通常对应一个屏幕,用户能在这个屏幕上进行交互操作。Activity管理应用的UI布局,并处理用户的输入和导航。

  • 特点
    • 用户界面:展示应用的UI。
    • 生命周期:Activity有一套完整的生命周期管理方法,如、、、、、等,用于管理其状态变化。
    • 交互逻辑:处理用户输入和事件。

2. Service(服务)

Service是一个可以在后台长时间运行的组件。它不提供用户界面,但可以执行需要持续进行的操作,如播放音乐、下载文件或执行网络请求。

  • 特点
    • 后台运行:可以在后台运行,即使用户退出应用。
    • 无UI:不提供用户界面。
    • 生命周期:Service也有自己的生命周期管理方法,如、、、等。

3. BroadcastReceiver(广播接收器)

BroadcastReceiver允许应用接收并处理广播消息。广播可以来自系统或其他应用,用于通知一些全局的事件,如电量变化、网络状态变化、短信接收等。

  • 特点
    • 接收广播:能够接收和处理广播消息。
    • 无持续运行:广播接收器在处理完广播后会立即停止,不会长期运行。
    • 动态和静态注册:可以在代码中动态注册,也可以在文件中静态注册。

4. ContentProvider(内容提供者)

ContentProvider为应用程序之间共享数据提供了统一的接口。它可以用来存储和检索数据,并允许不同应用访问这些数据。常见的使用场景包括访问联系人、图片、视频等。

  • 特点
    • 数据共享:允许应用程序之间共享数据。
    • 标准接口:提供一套标准的接口用于数据的CRUD操作(创建、读取、更新、删除)。
    • URI标识:通过URI标识要访问的数据。

示例使用场景

  1. Activity
    1. 打开一个新的界面,例如启动一个新的Activity来显示详细信息。
  2. Service
    1. 播放背景音乐,即使用户切换到其他应用,音乐仍然在后台播放。
  3. BroadcastReceiver
    1. 当收到新短信时显示通知,或者当网络状态变化时通知用户。
  4. ContentProvider
    1. 读取系统通讯录中的联系人信息并显示在应用中。
  1. .gradle和.idea
    1. 这两个目录下放置的都是Android Studio自动生成的一些文件,我们无须关心,也不要去手动编辑
  2. app
    1. 项目中的代码、资源等内容都是放置在这个目录下的,我们后面的开发工作也基本是在这个目录下进行的,待会儿还会对这个目录单独展开讲解。
  3. build
    1. 这个目录主要包含了一些在编译时自动生成的文件,你也不需要过多关心
  4. gradle
    1. 这个目录下包含了gradle wrapper的配置文件,使用gradle wrapper的方式不需要提前将gradle下载好,而是会自动根据本地的缓存情况决定是否需要联网下载gradle。
    2. Android Studio默认就是启用gradle wrapper方式的,如果需要更改成离线模式,可以点击Android Studio导航栏→File→Settings→Build, Execution,Deployment→Gradle,进行配置更改
  5. .gitignore
    1. 这个文件是用来将指定的目录或文件排除在版本控制之外的。
  6. build.gradle
    1. 这是项目全局的gradle构建脚本,通常这个文件中的内容是不需要修改的。稍后我们将会详细分析gradle构建脚本中的具体内容。
  7. gradle.properties
    1. 这个文件是全局的gradle配置文件,在这里配置的属性将会影响到项目中所有的gradle编译脚本。
  8. gradlew和gradlew.bat
    1. 这两个文件是用来在命令行界面中执行gradle命令的,
    2. 其中gradlew是在Linux或Mac系统中使用的,gradlew.bat是在Windows系统中使用的。
  9. HelloWorld.imliml
    1. 文件是所有IntelliJ IDEA项目都会自动生成的一个文件(Android Studio是基于IntelliJIDEA开发的),用于标识这是一个IntelliJ IDEA项目,我们不需要修改这个文件中的任何内容。
  10. local.properties
    1. 这个文件用于指定本机中的Android SDK路径,通常内容是自动生成的,我们并不需要修改。除非你本机中的Android SDK位置发生了变化,那么就将这个文件中的路径改成新的位置即可。
  11. settings.gradle
    1. 这个文件用于指定项目中所有引入的模块。由于HelloWorld项目中只有一个app模块,因此该文件中也就只引入了app这一个模块。通常情况下,模块的引入是自动完成的,需要我们手动修改这个文件的场景可能比较少
  1. build
    1. 这个目录和外层的build目录类似,也包含了一些在编译时自动生成的文件,不过它里面的内容会更加复杂,我们不需要过多关心。
  2. libs
    1. 如果你的项目中使用到了第三方jar包,就需要把这些jar包都放在libs目录下,放在这个目录下的jar包会被自动添加到项目的构建路径里。
  3. androidTest
    1. 此处是用来编写Android Test测试用例的,可以对项目进行一些自动化测试。
  4. java
    1. 毫无疑问,java目录是放置我们所有Java代码的地方(Kotlin代码也放在这里),展开该目录,你将看到系统帮我们自动生成了一个MainActivity文件。
  5. res
    1. 这个目录下的内容就有点多了。简单点说,就是你在项目中使用到的所有图片、布局、字符串等资源都要存放在这个目录下。
    2. 当然这个目录下还有很多子目录,图片放在drawable目录下,布局放在layout目录下,字符串放在values目录下,所以你不用担心会把整个res目录弄得乱糟糟的。
  6. AndroidManifest.xml
    1. 这是整个Android项目的配置文件,你在程序中定义的所有四大组件都需要在这个文件里注册,另外还可以在这个文件中给应用程序添加权限声明。由于这个文件以后会经常用到,我们等用到的时候再做详细说明。
  7. test
  8. 此处是用来编写Unit Test测试用例的,是对项目进行自动化测试的另一种方式。
  9. .gitignore
    1. 这个文件用于将app模块内指定的目录或文件排除在版本控制之外,作用和外层的.gitignore文件类似。
  10. app.iml
    1. IntelliJ IDEA项目自动生成的文件,我们不需要关心或修改这个文件中的内容。
  11. build.gradle
    1. 这是app模块的gradle构建脚本,这个文件中会指定很多项目构建相关的配置,我们稍后将会详细分析gradle构建脚本中的具体内容。
  12. proguard-rules.pro
    1. 这个文件用于指定项目代码的混淆规则,当代码开发完成后打包成安装包文件,如果不希望代码被别人破解,通常会将代码进行混淆,从而让破解者难以阅读。

Android-Manifest.xml文件

 

这段代码表示对MainActivity进行注册,没有在AndroidManifest.xml里注册的Activity是不能使用的。

其中intent-filter里的两行代码非常重要, 和表示MainActivity是这个项目的主Activity,在手机上点击应用图标,首先启动的就是这个Activity。

Activity是Android应用程序的门面,凡是在应用中你看得到的东西,都是放在Activity中的

MainActivity文件

书中

首先可以看到,MainActivity是继承自AppCompatActivity的。

AppCompatActivity是AndroidX中提供的一种向下兼容的Activity,可以使Activity在不同系统版本中的功能保持一致性。

而Activity类是Android系统提供的一个基类,我们项目中所有自定义的Activity都必须继承它或者它的子类才能拥有Activity的特性(AppCompatActivity是Activity的子类)。

然后可以看到MainActivity中有一个onCreate()方法,这个方法是一个Activity被创建时必定要执行的方法,其中只有两行代码,并且没有“Hello World! ”的字样。

新版
 

  • 作用:调用父类 的 方法,执行基类的初始化代码。这是确保Activity生命周期方常工作的必要步骤。

  • 作用:启用Edge-to-Edge模式,使Activity可以使用整个屏幕区域,包括系统栏。具体实现可能依赖于自定义的 类。

  • 作用:设置Activity的布局资源。 指向一个XML布局文件,定义了这个Activity的用户界面。

  • 作用:设置一个窗口内边距监听器,监听系统窗口内边距的变化(如状态栏和导航栏)。
  • 具体步骤
    • :找到布局中的 视图。
    • :设置一个监听器,在窗口内边距发生变化时调用。
    • :Lambda表达式,定义了在窗口内边距发生变化时执行的代码。
      • :获取系统栏的内边距(状态栏和导航栏)。
      • :根据系统栏的内边距设置视图的填充。
      • :返回原始的内边距对象。

整体流程

  1. 调用父类 方法:确保Activity生命周期的正常运作。
  2. 启用Edge-to-Edge模式:使内容可以延伸到系统栏区域。
  3. 设置内容视图:加载并显示布局文件 。
  4. 设置窗口内边距****监听器:调整视图的填充,使其内容不会被系统栏遮挡。

那么“Hello World! ”是在哪里定义的呢?其实Android程序的设计讲究逻辑和视图分离,因此是不推荐在Activity中直接编写界面的。

一种更加通用的做法是,在布局文件中编写界面,然后在Activity中引入进来。

可以看到,在onCreate()方法的第二行调用了setContentView()方法,就是这个方法给当前的Activity引入了一个activity_main布局,那“Hello World!”一定就是在这里定义的了!我们快打开这个文件看一看

布局文件都是定义在res/layout目录下的,当你展开layout目录,你会看到activity_main.xml这个文件。打开该文件并切换到Text视图,代码如下所示:

 

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

然后你终于在TextView中看到了“Hello World!”的字样!哈哈!终于找到了,原来就是

通过android:text="Hello World!"这句代码定义的

看到这么多的子目录也不用害怕,其实归纳一下,res目录中的内容就变得非常简单了。

所有以“drawable”开头的目录都是用来放图片的,

所有以“mipmap”开头的目录都是用来放应用图标的,

所有以“values”开头的目录都是用来放字符串、样式、颜色等配置的,

所有以“layout”开头的目录都是用来放布局文件的。

怎么样,是不是突然感觉清晰了很多?

之所以有这么多“mipmap”开头的目录,其实主要是为了让程序能够更好地兼容各种设备。

drawable目录也是相同的道理,虽然Android Studio没有帮我们自动生成,但是我们应该自己创建drawable-hdpi、drawable-xhdpi、drawable-xxhdpi等目录。在制作程序的时候,最好能够给同一张图片提供几个不同分辨率的版本,分别放在这些目录下,然后程序运行的时候,会自动根据当前运行设备分辨率的高低选择加载哪个目录下的图片。当然这只是理想情况,更多的时候美工只会提供给我们一份图片,这时你把所有图片都放在drawable-xxhdpi目录下就好了,因为这是最主流的设备分辨率目录。

知道了res目录下每个子目录的含义,我们再来看一下如何使用这些资源吧。

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

 

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

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

基本的语法就是上面这两种方式,

其中string部分是可以替换的,

如果是引用的图片资源就可以替换成drawable,

如果是引用的应用图标就可以替换成mipmap,

如果是引用的布局文件就可以替换成layout

打开AndroidManifest.xml文件,找到如下代码:

 

其中,HelloWorld项目的应用图标就是通过android:icon属性指定的,应用的名称则是通过android:label属性指定的。可以看到,这里对资源引用的方式正是我们刚刚学过的在XML中引用资源的语法。

build.gradle文件

不同于Eclipse,Android Studio是采用Gradle来构建项目的。Gradle是一个非常先进的项目构建工具,它使用了一种基于Groovy的领域特定语言(DSL)来进行项目设置,摒弃了传统基于XML(如Ant和Maven)的各种烦琐配置。

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

这两个文件对构建Android Studio项目都起到了至关重要的作用,下面我们就来对这两个文件中的内容进行详细的分析。先来看一下最外层目录下的build.gradle文件,代码如下所示:

上为书中原代码,下为当前as版本的代码

 
1.Gradle插件是配置项目构建和管理依赖项
书中

这个文件中的内容就要相对复杂一些了,下面我们一行行地进行分析。首先第一行应用了一个插件,一般有两种值可选:com.android.application表示这是一个应用程序模块,

com.android.library表示这是一个库模块。二者最大的区别在于,应用程序模块是可以直接运行的,库模块只能作为代码库依附于别的应用程序模块来运行。

接下来的两行应用了kotlin-android和kotlin-android-extensions这两个插件。如果你想要使用Kotlin来开发Android项目,那么第一个插件就是必须应用的。而第二个插件帮助我们实现了一些非常好用的Kotlin扩展功能,在后面的章节中,你将能体会到它所带来的巨大便利性。

新版
 

第一行使用版本目录 () 的 块,

要在项目的目录下创建一个 文件,用于定义插件和库的版本。

在项目根级的 文件中启用版本目录,并加载 文件。

在 文件中配置插件管理。

在应用模块的 文件中,使用 来应用插件,并引用版本目录中的插件和依赖项。

这里是关于这个插件的使用(在看书时,发现第一行代码的2,3版不一样,并且与当前的as的配置文件也不一样)

Gradle插件使用

2.android闭包
1.defaultConfig
书中

紧接着是一个大的android闭包,在这个闭包中我们可以配置项目构建的各种属性。

其中,compileSdkVersion用于指定项目的编译版本,这里指定成29表示使用Android 10.0系统的SDK编译。

buildToolsVersion用于指定项目构建工具的版本,目前最新的版本就是29.0.2,如果有更新的版本时,Android Studio会进行提示。

标红部分被高亮标红部分替代

新版

  • 作用:指定应用程序的命名空间。这是Java/Kotlin包名的替代方案,在应用模块的源码包名和资源包名之间建立联系。它用于唯一标识应用程序,特别是在混淆和打包时使用。

  • 作用:指定编译应用程序时使用的Android SDK版本。这个版本决定了应用程序可以使用的API和功能。通常,建议使用最新的稳定版本。
  • 版本 34:表示编译时使用的Android 34版SDK。

块定义了应用程序的默认配置。下面是各个配置项的详细说明:

  • 作用:唯一标识应用程序。这个ID在整个应用程序的生命周期内保持不变,通常遵循域名反转的命名规则。
  • 示例值
  • 作用:指定应用程序支持的最低Android SDK版本。应用程序将无法在低于该版本的设备上安装和运行。
  • 版本 31:表示应用程序至少支持Android 12(API 31)。
  • 作用:指定应用程序的目标Android SDK版本。这个版本表示应用程序经过测试并优化的SDK版本。目标版本可以启用新版本的行为和功能,同时保持旧版本的兼容性。
  • 版本 34:表示应用程序针对Android 34进行优化。
  • 作用:应用程序的内部版本号,每次发布新版本时都应递增。它用于区分不同的版本,特别是在应用商店中进行版本管理时。
  • 示例值:(初始版本)
  • 作用:应用程序的版本名称,对用户可见。它可以包含任何字符串,通常用来表示人类可读的版本号。
  • 示例值:(初始版本)
  • 作用:指定用于运行Android仪器化测试的运行器类。通常使用AndroidX提供的 来运行JUnit测试。
  • 示例值
2.buildTypes

buildTypes闭包中用于指定生成安装文件的相关配置,通常只会有两个子闭包:一个是debug,一个是release。debug闭包用于指定生成测试版安装文件的配置,release闭包用于指定生成正式版安装文件的配置。

另外,debug闭包是可以忽略不写的,因此我们看到上面的代码中就只有一个release闭包。

下面来看一下release闭包中的具体内容吧,

  1. minifyEnabled用于指定是否对项目的代码进行混淆,true表示混淆,false表示不混淆。
  2. proguardFiles用于指定混淆时使用的规则文件,这里指定了两个文件:
    1. 第一个proguard-android-optimize.txt是在/tools/proguard目录下的,里面是所有项目通用的混淆规则;
    2. 第二个proguard-rules.pro是在当前项目的根目录下的,里面可以编写当前项目特有的混淆规则。

需要注意的是,通过Android Studio直接运行项目生成的都是测试版安装文件,关于如何生成正式版安装文件,我们将会在之后学习。

此处新版与书中一样,不再赘述。

3.compileOptions(新版有的,书中没有该代码)

属性

  • sourceCompatibility:指定Java源代码的版本。这个版本定义了代码中的语法和语言特性。
  • targetCompatibility:指定编译后的字节码的版本。这个版本定义了生成的字节码可以在哪些版本的Java虚拟机上运行。

示例

 

上面的配置指定了Java 8作为源代码和目标字节码的版本。这意味着你可以在代码中使用Java 8的语言特性,并且生成的字节码可以在支持Java 8的JVM上运行。

3.dependencies

这个闭包的功能非常强大,它可以指定当前项目所有的依赖关系。

通常Android Studio项目一共有3种依赖方式:本地依赖、库依赖和远程依赖。

本地依赖可以对本地的jar包或目录添加依赖关系,

库依赖可以对项目中的库模块添加依赖关系,

远程依赖则可以对jcenter仓库上的开源项目添加依赖关系。

书中:
  1. implementation fileTree就是一个本地依赖声明,它表示将libs目录下所有.jar后缀的文件都添加到项目的构建路径中。
  2. implementation则是远程依赖声明,
    1. androidx.appcompat:appcompat:1.1.0就是一个标准的远程依赖库格式,
      1. 其中androidx.appcompat是域名部分,用于和其他公司的库做区分;
      2. appcompat是工程名部分,用于和同一个公司中不同的库工程做区分;
      3. 1.1.0是版本号,用于和同一个库不同的版本做区分。加上这句声明后,Gradle在构建项目时会首先检查一下本地是否已经有这个库的缓存,如果没有的话则会自动联网下载,然后再添加到项目的构建路径中。
  3. 至于库依赖声明这里没有用到,它的基本格式是implementation project后面加上要依赖的库的名称,
    1. 比如有一个库模块的名字叫helper,那么添加这个库的依赖关系只需要加入implementation project(‘:helper’)这句声明即可。

另外剩下的testImplementation和androidTestImplementation都是用于声明测试用例库的,这个我们暂时用不到,先忽略它就可以了

新版
 

依赖项解释

  • 作用: 配置表示该依赖项在编译和运行时都需要。
  • 例子
    • :引用 库,提供兼容性支持,用于向后兼容的应用程序开发。
    • :引用 库,用于使用Material Design组件。
    • :引用 库,提供Activity相关的扩展功能。
    • :引用 库,用于创建复杂布局的ConstraintLayout组件。
  • 作用: 配置表示该依赖项仅在运行单元测试时需要。
  • 例子
    • :引用 库,用于编写和运行单元测试。
  • 作用: 配置表示该依赖项仅在运行Android仪器化测试时需要。
  • 例子
    • :引用 库,用于在Android环境中运行JUnit测试。
    • :引用 库,用于编写UI测试。

LogAndroid中的日志工具类是Log(android.util.Log),

这个类中提供了如下5个方法来供我们打印日志。

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

其实很简单,一共就5个方法,当然每个方法还会有不同的重载,但那对你来说肯定不是什么难理解的地方了。我们现在就在HelloWorld项目中试一试日志工具好不好用吧。

打开MainActivity,在onCreate()方法中添加一行打印日志的语句,如下所示:

 

Log.d()方法中传入了两个参数:

  1. 第一个参数是tag,一般传入当前的类名就好,主要用于对打印信息进行过滤;
  2. 第二个参数是msg,即想要打印的具体内容。

现在可以重新运行一下HelloWorld这个项目了,点击顶部工具栏上的运行按钮,或者使用快捷键Shift + F10(Mac系统是control + R)。

等程序运行完毕,点击Android Studio底部工具栏的“Android Monitor”,在Logcat中就可以看到打印信息了

Logcat中的打印信息

其中,你不仅可以看到打印日志的内容和tag名,就连程序的包名、打印的时间以及应用程序的进程号都可以看到。

当然,Logcat中不光会显示我们所打印的日志,还会显示许多其他程序打印的日志,因此在很多情况下还需要对日志进行过滤

为什么System.out.println()和println()方这么不受待见呢?经过我仔细分析之后,发现这两个方法除了使用方便一点之外,其他就一无是处了。方便在哪儿呢?在AndroidStudio中你只需要输入“sout”,然后按下代码提示键,方法就会自动出来了,相信这也是很多Java新手对它钟情的原因。

那缺点又在哪儿了呢?这个就太多了,比如日志开关不可控制、不能添加日志标签、日志没有级别区分…听我说了这些,你可能已经不太想用System.out.println()和println()方法了,

那么Log就把上面所说的缺点全部改好了吗?虽然谈不上全部,但我觉得Log已经做得相当不错了。我现在就来带你看看Log和Logcat配合的强大之处

过滤器

首先,Logcat中可以很轻松地添加过滤器

目前只有3个过滤器,Show only selected application表示只显示当前选中程序的日志;

Firebase是Google提供的一个开发者工具和基础架构平台,我们可以不用管它;

No Filters相当于没有过滤器,会把所有的日志都显示出来。

那可不可以自定义过滤器呢?当然可以,我们现在就来添加一个过滤器试试。

  1. 点击“Edit Filter Configuration”,会弹出一个过滤器配置界面。
  2. 我们给过滤器起名叫data,并且让它对名为data的tag进行过滤。
  3. 点击“OK”,你会发现多出了一个data过滤器。
  4. 当选中这个过滤器的时候,刚才在onCreate()方法里打印的日志就不见了,这是因为data这个过滤器只会显示tag名称为data的日志。
  5. 你可以尝试在onCreate()方法中把打印日志的语句改成Log.d(“data”, “onCreateexecute”),然后再次运行程序,你就会在data过滤器下看到这行日志了

以上是老版本过滤器,不适用于2022十月之后的。

下来是新版使用方法:

在绿色的packege后面用空格加上tag:date就可以达到上述效果,除此之外还有其他的更多的过滤方法,有大佬进行了整理。

level: 表示log的等级,对应debug、error等等

package: 代表包名

tag: 代表标签筛选

-tag: 则代表过滤标签,设置的tag不显示

这里我们直接上链接

https://blog.csdn.net/qq_20451879/article/details/134694630

https://blog.csdn.net/woailinqingxia/article/details/134820595

也可以过滤其中的几项。按自己需求过滤

老版本的只能过滤一个包名,或一个TAG,或关键字,新版本的还是很好用的。

日志

看完了过滤器,再来看一下Logcat中的日志级别控制吧。Logcat中主要有5个级别,分别对应上一小节介绍的5个方法

当前我们选中的级别是Verbose,也就是最低等级。这意味着不管我们使用哪一个方法打印日志,这条日志都一定会显示出来。而如果我们将级别选中为Debug,这时只有我们使用Debug

及以上级别方法打印的日志才会显示出来,以此类推。你可以做一下实验,当你把Logcat中的级别选中为Info、Warn或者Error时,我们在onCreate()方法中打印的语句是不会显示的,因为我们打印日志时使用的是Log.d()方法

器下看到这行日志了

以上是老版本过滤器,不适用于2022十月之后的。

下来是新版使用方法:

[外链图片转存中…(img-80VzIoQ4-1721461921332)]

在绿色的packege后面用空格加上tag:date就可以达到上述效果,除此之外还有其他的更多的过滤方法,有大佬进行了整理。

level: 表示log的等级,对应debug、error等等

package: 代表包名

tag: 代表标签筛选

-tag: 则代表过滤标签,设置的tag不显示

这里我们直接上链接

https://blog.csdn.net/qq_20451879/article/details/134694630

https://blog.csdn.net/woailinqingxia/article/details/134820595

也可以过滤其中的几项。按自己需求过滤

老版本的只能过滤一个包名,或一个TAG,或关键字,新版本的还是很好用的。

日志

看完了过滤器,再来看一下Logcat中的日志级别控制吧。Logcat中主要有5个级别,分别对应上一小节介绍的5个方法

当前我们选中的级别是Verbose,也就是最低等级。这意味着不管我们使用哪一个方法打印日志,这条日志都一定会显示出来。而如果我们将级别选中为Debug,这时只有我们使用Debug

及以上级别方法打印的日志才会显示出来,以此类推。你可以做一下实验,当你把Logcat中的级别选中为Info、Warn或者Error时,我们在onCreate()方法中打印的语句是不会显示的,因为我们打印日志时使用的是Log.d()方法

重庆版权声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕,E-mail:xinmeigg88@163.com

展开全文READ MORE
第一行
python 贴吧自动回复机-python实现微信自动回复机器人功能 iOS模拟器云手机,多开模式让你欢乐无限