• 02 - 分析一个Android程序以及日志工具的使用


    一、 Android模式的项目结构

    所有的一、 二、 三这些结构分析, 大致上有一个概念就可以了, 等对Android有了基本的概念, 再回来了解整体项目结构。

    • 一个新建的项目会默认使用Android模式的项目结构(如图1所示), 但是这不是项目真实的目录结构, 而是经过Android Studio转换过的, 可以选择切换成Project结构(如图3所示), 这就是项目真实的目录结构
    • 图1在这里插入图片描述
    • 图2在这里插入图片描述
    • 图3在这里插入图片描述

    二、 Project模式的整体项目结构

    1. .gradle 和 .idea

    • 这两个目录下放置的都是Android Studio自动生成的一些文件

    2. app

    在这里插入图片描述

    • 项目中的代码、资源等内容几乎都是放置在这个目录下的

    3. build

    • 包含在编译时自动生成的文件

    4. gradle

    • 在这里插入图片描述
    • 包含了gradle wrapper的配置, 使用gradle wrapper的方式不需要提前将gradle下载好, 而是会自动根据本地的缓存情况决定是否需要联网下载gradle。Android Studio默认没有启用gradle wrapper的方式, 如果需要打开, 可以点击Android Studio导航栏->File->Settings->Build, Execution,Deployment->Build Tools->Gradle, 进行配置更改;

    在这里插入图片描述

    5. .gitignore

    • 这个文件是用来将指定的目录或文件排除在版本控制之外的;(后面会介绍版本控制)

    6. buil.gradle

    • 这是项目全局的gradle构建脚本, 通常这个文件中的内容是不需要修改的。

    7. gradle.properties

    • 这个文件是全局的gradle配置文件, 在这里配置的属性将会影响到项目中所有gradle编译脚本;

    8. gradlew和gradlew.bat

    • 这两个文件是用来在命令行界面中执行gradle命令的, 其中gradlew是在Linux或Mac系统中使用的, gradlew.bat是在Windows系统中使用的。

    9. local.properties

    • 这个文件用于指定本机中的Android SDK路径, 通常内容都是自动生成的, 并不需要修改;当本机中的Android SDK位置发生了变化, 那么就将这个文件中的路径改成新的位置即可。
    • 在这里插入图片描述
    • 在这里插入图片描述

    10. settings.gradle

    • 这个文件用于指定项目中所有引入的模块。由于我这个项目中就只有一个app模块, 因此该文件中也就只引入了app这一个模块。通常情况下模块的引入都是自动完成的。

    三、 Project 模式下app目录下的内容分析

    在这里插入图片描述

    1. build

    • 这个目录和外层的build目录类似, 主要也是包含了一些在编译时自动生成的文件, 不过它里面的内容会更多更杂

    2. libs

    • 若项目中用到了第三方jar包, 就需要把这些jar包都放在libs目录下, 放在这个目录下的jar包都会被自动添加到构建路径里去。

    3. src下的androidTest

    • 用来编写Android Test测试用例的, 可以对项目进行一些自动化测试。

    4. main下的java

    在这里插入图片描述

    • java目录是放置我们所有Java代码的地方, 展开该目录, 将看到创建的MainActivity文件。

    5. res

    在这里插入图片描述

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

    6. AndroidManifest.xml

    • 这是整个Android项目的配置文件, 在程序中定义的所有四大组件都需要在这个文件里面注册, 另外还可以在这个文件中给应用程序添加权限声明, 比如要获得拨打电话权限等等。
      在这里插入图片描述

    7. test

    在这里插入图片描述

    • 这是用来编写Unit Test测试用例的, 是对项目进行自动化测试的另一种方式。

    8. .gitignore (可以和上面的.gitignore对比)

    在这里插入图片描述

    • 这个文件是用于将app模块内的指定的目录或文件排除在版本控制之外,作用和外层的.gitignore文件类似。

    9. build.gradle

    • 这是app模块的gradle构建脚本, 这个文件中会指定很多项目构建相关的配置。

    10. proguard-rules.pro

    • 这个文件用于指定项目代码的混淆规则, 当代码开发完成后打成安装包文件, 如果不希望代码被别人破解, 通常会将代码进行混淆, 从而让破解者难以阅读。

    四、 分析一个Android项目是如何运行起来的

    1. 先从AndroidManifest.xml文件开始看起:

     <activity android:name=".MainActivity"
                android:exported="true">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN"/>
                    <category android:name="android.intent.category.LAUNCHER"/>
                </intent-filter>
    </activity>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 这段代码表示的是对MainActivity这个活动进行注册, 没有在AndroidManifest.xml(清单文件)里注册的活动是不能使用的。
    • 在intent-filter里的两行代码是非常重要的, 在这里插入图片描述 表示MainActivity是这个项目的主活动;在这里插入图片描述则表示在手机上点击应用图标, 首先启动的就是这个活动

    2. MainActivity的作用:

    • 之前介绍Android四大组件的时候说过了, Activity(活动)是Android应用程序的门面, 只要在应用中可以看到的东西, 全是放在活动中的;
    • 在这里插入图片描述
    • 启动app后看到的界面, 就是MainActivity这个活动;

    3. MainActivity中的代码

    • 关键代码提取如下:
    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main_activity);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • MainActivity继承自AppCompatActivity, AppCompatActivity是一种向下兼容的Activity, 可以将Activity在各个系统版本中增加的特性和功能最低兼容到Android 2.1系统。
    • AppCompatActivity是Activity的子类, 而Activity是Android系统提供的一个活动基类, 项目中的所有活动都必须继承Activity或者Activity的子类才能拥有活动的特性。
    • 在代码中可以看到onCreate()方法, 这个方法是一个活动被创建时必定要执行的方法。可以看到这里代码很少, 好像没有体现出刚才看到的界面。
    • 因为在Android中, 程序的设计讲究逻辑和视图分离, 所以不会在一个Activity中直接编写界面, 而是在布局文件中编写界面, 然后在活动(Activity)中引入进来。
      • 所以, 可以看到在方法中调用了setContentView()方法, 传入参数R.layout.main_activity, 这样就为当前的活动引入了一个layout.main_activity布局;
    • 进入layout.main_activity.xml文件可以看到, 界面的设计代码:
      • 在这里插入图片描述

    五、 项目中的资源res目录

    在这里插入图片描述

    • 所有以drawable开头的文件夹都是用来放图片的;
      • 同有那么多mipmap开头的文件夹是一样的道理, 为了让程序兼容各种设备, 这里也应该有很多以drawable开头的文件夹, 虽然Android Studio没有帮我们自动生成, 但是考虑到程序要兼容更多的设备, 应该自己创建drawable-hdpi, drawable-xhdpi, drawable-xxhdpi等文件夹;
      • 分辨率是指屏幕上横竖各有多少个像素
      • 不同drawable目录下对应图片分辨率:
      • drawable-ldpi:240x320(低分辨率的图片)
      • drawable-mdpi:320x480(中等分辨率的图片)
      • drawable-hdpi:480x800、480x854(高分辨率的图片)
      • drawable-xhdpi:至少960*720(高分辨率的图片)
      • drawable-xxhdpi:1280×720(高分辨率的图片)
    • 所有以mipmap开头的文件夹都是用来放应用图标的;
      • 有这么多mipmap开头的文件夹都是为了让程序能够更好的兼容各种设备。
    • 所有以values开头的文件夹都是用来放字符串、样式、颜色等配置的;
    • layout文件夹是用来放布局文件的。
    • 前面说过为了考虑到程序要兼容各种设备, 在开发程序的时候, 最后能给同一张图片提供几个不同分辨率的版本,分别放在这些文件夹下, 如果实在只有一份图片的话, 就全放在drawable-xxhdpi文件夹下就好;

    1. 简单分析res->values->strings.xml文件

    <resources>
        <string name="app_name">MusicPlayer</string>
    </resources>
    
    • 1
    • 2
    • 3
    • 由代码可以看到, 这里为字符串值 MusicPlayer定义了一个标识app_name, 可以用如下两种方式来引用这个字符串;
      • 在逻辑代码中, 通过R.string.app_name获得该字符串的引用;
      • 在layout, xml中, 通过@string/app_name可以获得该字符串的引用;
    • 其中string的部分是可以替换的, 如果是引用的图片资源就可以替换成drawable, 如果是引用的应用图标就可以替换成mipmap, 如果是引用的布局文件就可以替换成layout;
    • 就比如, AndroidManifest.xml中的这一段代码:对是对各种不同资源的引用
      • 在这里插入图片描述

    六、 分析build.gradle文件

    • Android Studio中是采用Gradle来构建项目的。Gradle是个非常先进的项目构建工具, 它使用了一种基于Groovy的领域特定语言(DSL)来声明项目设置, 摒弃了传统基于XML(如Ant和Maven)的各种烦琐配置;
    • 在前面提到过一个Android项目中有两个build.gradle文件, 一个是在最外层目录下的, 一个是在app目录下的。
    • 这两个文件对构建Android Studio项目起了很大的作用。

    1. 最外层目录下的build.gradle

    • 关于build.gradle后面还会扩展;
    • 先分析一段常见的代码结构, 摘自《第一行代码(第二版)》:
    • 在这里插入图片描述
    • 这些代码是自动生成的, 在两处repositories的闭包中都声明了jcenter()这行配置, jcenter即代码托管仓库, 很多Android开源项目都会选择将代码托管到jcenter上, repositories就是提示代码仓库的地方;在声明了jcenter这行配置之后, 就可以在项目中引用任何jcenter上的开源项目了;
    • dependencies闭包中, 利用classpath声明了一个Gradle插件,之所以要特地声明这个插件是因为,Gradle不是专门为构建Android项目而开发的。Java、C++等多中项目都可以使用Gradle来构建, 所以要想使用它来构建Android项目, 则需要声明com.android.tools.build:gradle:2.2.0这个插件,其中最后面的部分是插件的版本号。
    • 通常情况下是不需要修改外层目录下的build.gradle文件中的内容, 除非要添加一些全局的项目构建配置;

    2. app目录下的build.gradle文件

    • 节选《第一行代码(第二版)》中的片段进行分析

    • 在这里插入图片描述

    • 第一行应用了一个插件apply plugin: ‘com.android.application’, 一般有两种值可以选:

      • com.android.application, 表示这是一个应用程序模块;
      • com.android.library, 表示这是一个库模块;
      • 二者的区别就是:应用程序模块可以直接运行, 而库模块只能作为代码库依附于别的应用程序模块来运行;

    1. android闭包

    • 接下来可以看到一个android闭包。在这个闭包中可以配置项目构建的各种属性。
      • compileSdkVersion:用于指定项目的编译版本, 这里指定成24表示使用Android7.0系统的SDK编译。
      • buildToolsVersion用于指定项目构建工具的版本;

    2. defaultConfig闭包

    • 在android闭包中嵌套的defaultConfig闭包可以对项目的更多细节进行配置
      • applicationId:用于指定项目的包名, 在创建项目的时候已经指定了包名, 后面想修改就是在这里进行修改的。
      • minSdkVersion:用于指定项目最低兼容的Android系统版本, 这里指定15, 表示最低兼容到Android 4.0系统。
      • targetSdkVersion:指定的值表示你在该目标版本上已经做过了充分的测试, 系统将会为你的应用程序启用一些最新的功能和特性。比如说Android 6.0系统中引入了运行时权限功能, 如果你将targetSdkVersion指定成23或者更高, 那么系统就会为你的程序启用运行时权限功能,而如果将targetSdkVersion指定成22, 就说明程序最高只在Android5.1系统上做过充分的测试, Android 6.0系统中引入的新功能自然就不会启用了;
      • versionCode:用于指定项目的版本号;
      • versionName:用于指定项目的版本名;
      • versionCode和versionName在生成安装文件的时候非常重要

    3. buildTypes闭包

    • buildTypes闭包用于指定生成安装文件的相关配置, 通常只会有两个子闭包, 一个是debug, 一个是release。
      • debug闭包用于指定生成测试版安装文件的配置;(这个闭包可以忽略不写)
      • release闭包用于指定生成正式版安装文件的配置;
        • minifyEnable:用于指定是否对项目的代码进行混淆, true代表混淆, false代表不混淆;
        • proguardFiles:用于指定混淆时使用的规则文件, 这里指定了两个文件, 一个是proguard-android.txt是在Android SDK目录下的, 里面是所有项目通用的混淆规则;第二个是proguard-rules.pro是在当前项目的根目录下,在里面可以编写当前项目特有的混淆规则。
    • 注意!:通过Android Studio直接运行项目生成的都是测试版安装文件;

    4. dependencies闭包

    • 这个闭包可以指定当前项目所有的依赖关系。
    • 通常Android Studio项目一共有3中依赖方式:本地依赖、库依赖和远程依赖
    • 本地依赖:可以对本地的jar包或者目录添加依赖关系;
    • 库依赖:可以对项目中的库模块添加依赖关系;
    • 远程依赖:可以对jcenter库上的开源项目添加依赖关系。
    • 第一行的compile fileTree就是一个本地依赖声明, 它表示将libs目录下所有.jar后缀的文件都添加到项目的构建路径当中。
    • 第二行的compile则是远程依赖声明, com.android.support:appcompat-v7:24.2.1就是一个标准的远程依赖库格式:
      • com.android.support是域名部分, 用于和其他公司的库做区分;
      • appcompat-v7是组名称, 用于和同一个公司中不同的库做区分;24.2.1是版本号用于和同一个库不同的版本做区分;所以加上这句声明之后, Gradle在构建项目时会首先检查一下本地是否已经有这个库的缓存, 如果没有的话会自动联网下载, 然后再添加到项目的构建路径当中。
      • 库依赖这里没有, 它的声明格式是compile project后面加上要依赖的库名称;例如有一个库模块的名字叫helper,则添加这个库的依赖关系只需要加上compile project(‘:helper’)这句声明即可;
      • testCompile是用于声明测试用例库的;

    七、日志工具的使用

    1. Android的日志工具Log

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

    1.1 测试, 用Log.d()打印日志信息

    • Log.d():需要两个参数, 第一个参数是tag,一般传入当前的类名就可以, 自己定义也可以, 这个tag主要是用于对打印信息进行过滤的;第二个参数是msg, 想要打印的具体的内容;

      • Show only selected application 表示只显示当前使用的程序
      • Firebase是Google提供的一个开发者工具和基础平台架构。
      • No Filters相当于没有过滤器
      • Edit Filter Configuration 就是自定义过滤器
    • 例如:(这里选的是,show only selected application 即只显示选定的应用程序)

      • 在这里插入图片描述
      • 接着将项目运行起来(快捷键shift + F10), 在Android Studio底部的工具栏的Logcat中就可以看到打印的信息, 这里可以过滤一下:
        • 在这里插入图片描述
        • 这里可以看到打印日志的内容和tag名, 还可以看到程序的包名、打印的时间以及应用程序的进程号。
    • 在这里还可以编辑过滤器配置,例如:在这里插入图片描述
      在这里插入图片描述

    1.2 用好Log提升开发效率

    • 相较于System.out, Log 能比它做到的不止一点, System.out的打印没有办法控制打印时间, 不可添加过滤器, 没有日志分级等等, 所以Log取代了System.out
    • 如果想打印一条debug级别的日志, 输入logd,按下TAB键, Android Studio就会自动补全一条完整的打印语句;其他级别的同理
    • 在onCreate方法的外面输入logt,按下TAB键, 就会以当前的类名作为值自动生成一个TAG常量
    • 还有上面介绍过的添加过滤器;
    • 在logcat中选择日志分级也是一个很重要的事情:
      • 在这里插入图片描述
      • 例如, 选择的是Verbose, 那么无论用什么级别的方法打印日志,就都会显示出来;而选择Debug, 那么只能用debug及debug以上级别的方法打印日志, 日志信息才会显示出来。
    • 这里还可以使用关键字过滤, 可以在输入框中输入关键字的内容, 这样只有关键字条件的日志信息才会显示出来, 而且关键字过滤支持正则表达式:
      • 在这里插入图片描述
  • 相关阅读:
    vue3项目搭建手册
    2023年9月青少年软件编程(Python) 等级考试试卷(一级)
    springboot集成rabbitmq:fanout、topic
    【安卓基础1】初识Android
    《牛客刷verilog》Part II Verilog进阶挑战
    嗨!不来看一下如何骚气十足的登陆MySQL嘛?
    【AI视野·今日Robot 机器人论文速览 第四十九期】Fri, 6 Oct 2023
    GPU架构与计算入门指南
    线程的六种状态
    运行deepspeech训练,报出如下错误,不知道如何解决
  • 原文地址:https://blog.csdn.net/weixin_43306271/article/details/126753063