【Android移动开发】helloworld项目文件剖析

本文讨论了一个Android应用的Gradle项目的各个方面。涵盖了Gradle的启动脚本,项目的配置文件(如build.gradle和gradle.properties),以及应用的源代码和资源文件。具体内容包括了项目结构、Gradle插件的配置、AndroidManifest.xml文件的设置、资源文件(包括布局文件、颜色定义、图标文件等)、以及单元测试的编写与运行。通过这些内容,我们了解了如何配置和管理Android应用项目,并且了解了如何使用Gradle来构建和测试应用。

一、项目文件

项目文件剖析:

D:.
├─.gradle
│  ├─6.7.1
│  │  ├─fileChanges
│  │  ├─fileHashes
│  │  └─vcsMetadata-1
│  ├─buildOutputCleanup
│  ├─checksums
│  ├─configuration-cache
│  └─vcs-1
├─.idea
│  ├─libraries
│  └─modules
│      └─app
├─app
│  ├─libs
│  └─src
│      ├─androidTest
│      │  └─java
│      │      └─com
│      │          └─example
│      │              └─myapplication
│      ├─main
│      │  ├─java
│      │  │  └─com
│      │  │      └─example
│      │  │          └─myapplication
│      │  └─res
│      │      ├─drawable
│      │      ├─drawable-v24
│      │      ├─layout
│      │      ├─mipmap-anydpi-v26
│      │      ├─mipmap-hdpi
│      │      ├─mipmap-mdpi
│      │      ├─mipmap-xhdpi
│      │      ├─mipmap-xxhdpi
│      │      ├─mipmap-xxxhdpi
│      │      ├─values
│      │      └─values-night
│      └─test
│          └─java
│              └─com
│                  └─example
│                      └─myapplication
└─gradle
    └─wrapper


.gradle:

6.7.1: 这个子目录包含Gradle版本6.7.1的特定文件。它包括文件更改记录、文件哈希以及版本控制系统元数据。
buildOutputCleanup: 该目录包含构建输出清理相关的文件。
checksums: 包含各种文件的校验和。
configuration-cache: 这个目录用于存储Gradle的配置缓存文件。
vcs-1: 这里存储了与版本控制系统相关的信息。
.idea:

libraries: 这个目录包含了项目中使用的库的配置文件。
modules: 这个目录包含了项目模块的配置文件,比如应用模块(app)的配置。
app:

libs: 这个目录用于存放第三方库文件(如.jar或.aar文件)。
src:
androidTest: 用于编写Android测试代码的目录。
main:
java: 存放主要的Java源代码文件。
res: 存放应用程序使用的各种资源文件,如布局文件、图像等。
test: 用于编写单元测试代码的目录。
gradle:

wrapper: 这个目录包含了Gradle Wrapper的相关文件,包括脚本和JAR文件。Gradle Wrapper用于在没有预先安装Gradle的情况下自动下载和运行Gradle。

根据你提供的目录结构,这是一个使用Android Studio创建的典型的Android项目。我会简要解释每个目录的作用:

app:这是你的应用程序模块,其中包含了应用的源代码、资源文件等。

libs:用于存放第三方库文件(如JAR文件)的目录。
src:源代码和资源文件的根目录。
androidTest:用于放置用于仪器测试的源代码文件。
java:用于存放仪器测试的Java源代码文件。
main:包含应用程序的主要源代码和资源文件。
java:Java源代码文件的根目录。
com:包名的起始点。
example:示例包名。
myapplication:应用程序包名。
res:资源文件的根目录。
drawable:存放位图图形文件。
drawable-v24:适用于API级别24及更高版本的位图图形文件。
layout:存放布局文件。
mipmap-anydpi-v26:适用于API级别26及更高版本的mipmap文件。
mipmap-hdpi、mipmap-mdpi、mipmap-xhdpi、mipmap-xxhdpi、mipmap-xxxhdpi:不同密度的应用图标。
values:存放各种资源值,如字符串、颜色、尺寸等。
values-night:适用于夜间主题的资源值。
test:用于放置单元测试的源代码文件。
java:存放单元测试的Java源代码文件。
gradle:用于存放Gradle构建系统的相关文件,其中wrapper目录包含了Gradle的Wrapper文件,用于下载和运行指定版本的Gradle。

二、详细解析

settings.gradle

这个 settings.gradle 文件指定了项目的名称和模块的结构。让我解释一下:

rootProject.name = “My Application”:这一行定义了根项目的名称为 “My Application”。这是整个项目的名称,它可以在Gradle脚本中通过rootProject.name来引用。

include ‘:app’:这一行指定了要包含的模块。在这种情况下,只有一个模块 app 被包含在项目中。:app 是该模块的路径,其中 : 表示根项目。这意味着 app 模块是根项目的直接子模块,是整个项目的一部分。

local.properties

local.properties 文件包含了与你本地配置相关的信息,这些信息通常是不应该被提交到版本控制系统中的。让我来解释一下文件的内容:

sdk.dir=D:\MyAndroid\sdk:这一行指定了Android SDK的位置。在这个例子中,SDK被安装在 D:\MyAndroid\sdk 目录下。这个路径告诉Gradle在哪里找到Android SDK,以便构建和编译你的应用程序。请注意,这个路径可能会因为你的本地配置而有所不同。

gradlew.bat(Windows运行脚本,可以不看)

这个 gradlew.bat 脚本是用于在Windows操作系统上启动Gradle的。让我解释一下它的主要部分:

@if “%DEBUG%” == “” @echo off:这一行用于关闭调试信息的输出。

set DIRNAME=%~dp0:这一行获取当前脚本的路径。

set APP_BASE_NAME=%~n0:这一行获取当前脚本的文件名(不包括扩展名)。

set APP_HOME=%DIRNAME%:这一行设置应用程序的主目录为当前脚本所在的目录。

set DEFAULT_JVM_OPTS=:这一行定义了默认的JVM选项。

if defined JAVA_HOME goto findJavaFromJavaHome:这一行检查是否已经设置了JAVA_HOME环境变量,如果设置了则跳转到findJavaFromJavaHome标签处。

set JAVA_EXE=java.exe:这一行定义了java.exe的默认位置。

%JAVA_EXE% -version >NUL 2>&1:这一行检查系统中是否存在java.exe。

if not “%OS%” == “Windows_NT” goto win9xME_args:这一行检查操作系统是否为Windows NT,如果不是,则跳转到win9xME_args标签处。

:win9xME_args到:win9xME_args_slurp之间的部分是用于在Windows 9x/ME系统中获取命令行参数的。

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar:这一行设置了Gradle Wrapper的JAR文件的路径作为类路径。

“%JAVA_EXE%” %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% “-Dorg.gradle.appname=%APP_BASE_NAME%” -classpath “%CLASSPATH%” org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%:这一行启动了Gradle Wrapper,并传递了一些参数。

gradlew

这是一个用于在UNIX系统上启动Gradle的 gradlew 脚本。让我解释一下它的主要部分:

PRG=“$0”:这一行获取脚本的路径。

while [ -h “$PRG” ] ; do:这一行用于解析符号链接。

APP_HOME=“pwd -P”:这一行获取应用程序的主目录。

APP_NAME=“Gradle”:这一行定义了应用程序的名称。

DEFAULT_JVM_OPTS=“”:这一行定义了默认的JVM选项。

if [ -n “$JAVA_HOME” ] ; then:这一行检查是否已经设置了 JAVA_HOME 环境变量。

JAVACMD=“java”:这一行定义了Java命令的位置。

MAX_FD=“maximum”:这一行定义了最大文件描述符的数量。

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar:这一行设置了Gradle Wrapper的JAR文件的路径作为类路径。

eval set – $DEFAULT_JVM_OPTS $JAVA_OPTS G R A D L E O P T S " − ¨ D o r g . g r a d l e . a p p n a m e = GRADLE_OPTS "\"-Dorg.gradle.appname= GRADLEOPTS"¨Dorg.gradle.appname=APP_BASE_NAME"" -classpath "“ C L A S S P A T H " ¨ o r g . g r a d l e . w r a p p e r . G r a d l e W r a p p e r M a i n " CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain " CLASSPATH"¨org.gradle.wrapper.GradleWrapperMain"APP_ARGS”:这一行收集了所有的参数,以便于执行Java命令。

gradle.properties

这是一个项目范围的Gradle设置文件。让我解释一下其中的内容:

org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8:这一行指定了用于Gradle守护进程的JVM参数。通过这些参数,你可以调整内存设置等。在这个例子中,指定了最大堆内存为2048MB,并且设置了文件编码为UTF-8。

android.useAndroidX=true:这一行指定了在项目中使用AndroidX包结构。AndroidX包结构使得清晰明了,可以区分哪些包是与Android操作系统捆绑在一起的,哪些包是与你的应用程序的APK捆绑在一起的。

build.gradle

这是一个顶层的构建文件,你可以在其中添加所有子项目/模块共有的配置选项。让我解释一下其中的内容:

buildscript {
    repositories {
        google()
        mavenCentral()
        jcenter()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.2.0"

        // 注意:不要在这里放置应用程序的依赖项;它们应该放在各个模块的 build.gradle 文件中
    }
}

buildscript:这个部分用于配置构建脚本的依赖和仓库。

repositories:这里定义了构建脚本使用的仓库。包括了 Google Maven 仓库、Maven 中央仓库和 JCenter 仓库。

dependencies:这里定义了构建脚本依赖的类路径。在这个例子中,使用的是 com.android.tools.build:gradle:4.2.0 版本的 Android Gradle 插件。

allprojects {
    repositories {
        google()
        mavenCentral()
        jcenter() // 警告:这个仓库很快将会关闭
    }
}

allprojects:这个部分用于配置所有项目的仓库。在这里,同样包括了 Google Maven 仓库、Maven 中央仓库和 JCenter 仓库。但需要注意的是,JCenter 仓库在注释中已经提到会很快关闭,所以建议尽快迁移到其他仓库。

task clean(type: Delete) {
    delete rootProject.buildDir
}

task clean(type: Delete):这个部分定义了一个名为 clean 的任务,用于清理构建产生的临时文件。执行该任务会删除根项目的 build 目录。

\gradle\wrapper\gradle-wrapper.properties

这是一个Gradle Wrapper的配置文件,用于指定Gradle的发行版本和下载路径。让我解释一下其中的内容:

distributionBase=GRADLE_USER_HOME:指定Gradle Wrapper的分发基础目录为GRADLE_USER_HOME。这意味着Gradle将被下载到用户的本地Gradle目录。

distributionUrl=https://services.gradle.org/distributions/gradle-6.7.1-bin.zip:指定Gradle的下载链接。在这个例子中,Gradle版本为6.7.1,下载链接为https://services.gradle.org/distributions/gradle-6.7.1-bin.zip。

distributionPath=wrapper/dists:指定Gradle分发文件的存储路径为wrapper/dists。

zipStorePath=wrapper/dists:指定Gradle分发文件的存储路径为wrapper/dists。
在这里插入图片描述

zipStoreBase=GRADLE_USER_HOME:指定Gradle分发文件的基础目录为GRADLE_USER_HOME。

proguard-rules.pro

这是一个ProGuard规则文件(proguard-rules.pro),用于指定在混淆和优化Android应用程序时要应用的规则。让我解释一下其中的内容:

# Add project specific ProGuard rules here.:这一行是一个注释,提醒你可以在这里添加特定于项目的ProGuard规则。

# You can control the set of applied configuration files using the proguardFiles setting in build.gradle.:这一行是一个注释,指出你可以通过在 build.gradle 中的 proguardFiles 设置来控制应用的配置文件集合。

# For more details, see http://developer.android.com/guide/developing/tools/proguard.html:这一行是一个注释,提供了ProGuard文档的链接,供你查阅更多详情。

# If your project uses WebView with JS, uncomment the following:这一行是一个注释,提示如果你的项目使用了带有JavaScript的WebView,则需要取消注释下面的规则,并指定JavaScript接口的完全限定类名。

#-keepclassmembers class fqcn.of.javascript.interface.for.webview {:这一行是一个ProGuard规则的例子,用于保留WebView中与JavaScript接口相关的类成员。

# Uncomment this to preserve the line number information for debugging stack traces.:这一行是一个注释,提示如果要保留用于调试堆栈跟踪的行号信息,则需要取消注释下面的规则。

#-keepattributes SourceFile,LineNumberTable:这一行是一个ProGuard规则的例子,用于保留源文件和行号表信息。

# If you keep the line number information, uncomment this to hide the original source file name.:这一行是一个注释,提示如果保留了行号信息,则需要取消注释下面的规则来隐藏原始源文件名。

#-renamesourcefileattribute SourceFile:这一行是一个ProGuard规则的例子,用于重命名源文件属性。

app\build.gradle

以下是一个用于构建Android应用程序的 build.gradle 文件的示例,我会解释其中的内容:

plugins {
    id 'com.android.application'
}

这里使用了 com.android.application 插件,它使得这个项目成为一个Android应用程序项目。

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.0"

    defaultConfig {
        applicationId "com.example.myapplication"
        minSdkVersion 15
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    }

android 块包含了Android构建设置,其中指定了编译SDK版本、构建工具版本、默认配置等。

defaultConfig 块定义了应用程序的默认配置,包括了应用程序ID、最小SDK版本、目标SDK版本、版本代码、版本名称等。

buildTypes 块定义了构建类型,这里只有一个 release 类型,其中指定了混淆(minifyEnabled)为 false,并指定了混淆规则文件(proguardFiles)。

compileOptions 块定义了编译选项,这里设置了源代码和目标代码的兼容性为Java 1.8版本。

dependencies {
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.2.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

dependencies 块定义了项目的依赖关系。这里包括了AppCompat库、Material库、ConstraintLayout库以及JUnit和Espresso的测试依赖。

\app\src\androidTest\java\com\example\myapplication\ExampleInstrumentedTest.java:package com.example.myapplication

这是一个用于Android设备上执行的仪器测试(Instrumented Test)的示例代码。让我解释一下其中的内容:

package com.example.myapplication;

import android.content.Context;

import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.*;

/**
 * Instrumented test, which will execute on an Android device.
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
    @Test
    public void useAppContext() {
        // Context of the app under test.
        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
        assertEquals("com.example.myapplication", appContext.getPackageName());
    }
}

package com.example.myapplication;:指定了这个测试类所在的包名。

@RunWith(AndroidJUnit4.class):这个注解指定了测试运行器,使用了AndroidJUnit4.class,这是JUnit测试框架针对Android的扩展。

public class ExampleInstrumentedTest {:定义了一个名为 ExampleInstrumentedTest 的测试类。

@Test:这个注解标记了一个测试方法。

public void useAppContext() {:这是一个测试方法,用于测试应用程序的上下文。

Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();:这一行获取了应用程序的上下文。

assertEquals(“com.example.myapplication”, appContext.getPackageName());:这一行使用断言来验证应用程序的包名是否为 “com.example.myapplication”。

\app\src\main\java\com\example\myapplication\MainActivity.java

以下是一个名为 MainActivity.java 的Java文件的示例代码。这是一个典型的Android活动(Activity)类,负责管理应用程序的主要界面。

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

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

package com.example.myapplication;:指定了这个类所在的包名。

import androidx.appcompat.app.AppCompatActivity;:导入了 AppCompatActivity 类,这是支持应用程序向后兼容的活动基类。

import android.os.Bundle;:导入了 Bundle 类,这是用于传递数据的Android基本数据类型。

public class MainActivity extends AppCompatActivity {:定义了一个名为 MainActivity 的类,并且继承自 AppCompatActivity 类。

@Override:这个注解表示重写了父类的方法。

protected void onCreate(Bundle savedInstanceState) {:这是一个重写的方法,当活动被创建时调用。

super.onCreate(savedInstanceState);:这一行调用了父类的 onCreate 方法。

setContentView(R.layout.activity_main);:这一行设置了活动的布局为 activity_main.xml。

\app\src\main\res

\app\src\main\res 目录包含了Android应用程序的资源文件,它们按照功能和类型进行了组织。让我逐一解释这些目录:

drawable:用于存储非向量图形资源文件(如PNG、JPEG等格式的图片)的目录。

drawable-v24:与 drawable 目录类似,但是这里存储的资源是专门为API级别24及更高版本的设备而设计的。

layout:用于存储布局文件(XML文件),定义了应用程序的用户界面布局。

mipmap-anydpi-v26:用于存储在API级别26及更高版本的设备上显示的应用图标资源文件。

mipmap-hdpi、mipmap-mdpi、mipmap-xhdpi、mipmap-xxhdpi、mipmap-xxxhdpi:这些目录分别用于存储不同密度(DPI)的应用程序图标资源文件。每个目录中的图标文件具有不同的分辨率,以适配不同密度的屏幕。

values:用于存储各种资源值文件(如字符串、颜色、尺寸等),这些值可以在应用程序的代码和布局文件中引用。

values-night:与 values 目录类似,但是这里存储的是夜间模式下的资源值文件,用于支持暗黑主题的应用程序。

UI设计部分:ic_launcher_background

这个矢量图形文件定义了一个108x108dp的视口,并在其中绘制了一个填充颜色为 #3DDC84 的矩形,以及一系列分割线,用于创建一个具有网格样式的背景。

<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="108dp"
    android:height="108dp"
    android:viewportWidth="108"
    android:viewportHeight="108">
    <!-- 定义了一个填充颜色为 #3DDC84 的矩形路径 -->
    <path
        android:fillColor="#3DDC84"
        android:pathData="M0,0h108v108h-108z" />
    <!-- 定义了多个竖直方向的直线路径,用于绘制分割线 -->
    <path
        android:fillColor="#00000000"
        android:pathData="M9,0L9,108"
        android:strokeWidth="0.8"
        android:strokeColor="#33FFFFFF" />
    <!-- 其他竖直方向的直线路径,以及水平方向的直线路径,用于绘制分割线 -->
    <!-- 这些路径组成了一个网格的样式,用于作为应用程序图标的背景 -->
</vector>

UI设计部分:ic_launcher_foreground

这个矢量图形文件定义了一个108x108dp的视口,并在其中绘制了两个路径。第一个路径使用渐变填充,用于创建前景效果,而第二个路径则是白色的填充,用于覆盖在前景效果之上。

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:aapt="http://schemas.android.com/aapt"
    android:width="108dp"
    android:height="108dp"
    android:viewportWidth="108"
    android:viewportHeight="108">
    <!-- 第一个路径定义了一个渐变填充,用于创建前景效果 -->
    <path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
        <aapt:attr name="android:fillColor">
            <gradient
                android:endX="85.84757"
                android:endY="92.4963"
                android:startX="42.9492"
                android:startY="49.59793"
                android:type="linear">
                <item
                    android:color="#44000000"
                    android:offset="0.0" />
                <item
                    android:color="#00000000"
                    android:offset="1.0" />
            </gradient>
        </aapt:attr>
    </path>
    <!-- 第二个路径定义了一个白色的填充,用于覆盖在前景效果之上 -->
    <path
        android:fillColor="#FFFFFF"
        android:fillType="nonZero"
        android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
        android:strokeWidth="1"
        android:strokeColor="#00000000" />
</vector>

app\src\main\res\layout\activity_main.xml

这个布局文件中只包含一个 TextView 元素,它会显示 “Hello World!” 文本。此 TextView 元素被放置在 ConstraintLayout 中,这是一个强大的布局容器,用于创建灵活的界面布局。 ConstraintLayout 使用约束来定义子视图之间的位置关系,这样可以轻松实现自适应和响应式设计。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <!-- TextView 是一个用于显示文本的基本 UI 元素 -->
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" <!-- 设置显示的文本内容为 "Hello World!" -->
        app:layout_constraintBottom_toBottomOf="parent" <!-- 设置底部约束为父布局的底部 -->
        app:layout_constraintLeft_toLeftOf="parent" <!-- 设置左侧约束为父布局的左侧 -->
        app:layout_constraintRight_toRightOf="parent" <!-- 设置右侧约束为父布局的右侧 -->
        app:layout_constraintTop_toTopOf="parent" /> <!-- 设置顶部约束为父布局的顶部 -->

</androidx.constraintlayout.widget.ConstraintLayout>


\app\src\main\res\mipmap-anydpi-v26\ic_launcher.xml

<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
    <background android:drawable="@drawable/ic_launcher_background" />
    <foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

这个 XML 文件定义了一个自适应图标,它由两个部分组成:背景 (background) 和前景 (foreground)。这些部分使用 @drawable/ic_launcher_background 和 @drawable/ic_launcher_foreground 引用了两个不同的图像资源。在 Android 应用程序中,图标通常分为背景和前景两个部分,以便在不同的设备和主题下显示时保持一致性和美观性。

app\src\main\AndroidManifest.xml

这个 XML 文件包含了关于应用程序的重要信息,包括包名、应用图标、主题等。其中, 元素指定了应用程序的主要活动(MainActivity),并设置了启动时的意图过滤器,使其成为应用程序的启动器活动。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapplication">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyApplication">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

\app\src\test\java\com\example\myapplication\ExampleUnitTest.java

package com.example.myapplication;

import org.junit.Test;

import static org.junit.Assert.*;

/**
 * Example local unit test, which will execute on the development machine (host).
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
public class ExampleUnitTest {
    @Test
    public void addition_isCorrect() {
        assertEquals(4, 2 + 2);
    }
}

这个单元测试文件中包含了一个测试方法 addition_isCorrect(),用于测试加法是否正确。在这个测试方法中,我们期望 2 加 2 的结果是 4,因此使用 assertEquals() 方法来断言这个期望的结果是否成立。

运行方法:

gradlew test

Welcome to Gradle 6.7.1!

Here are the highlights of this release:
 - File system watching is ready for production use
 - Declare the version of Java your build requires
 - Java 15 support

For more details see https://docs.gradle.org/6.7.1/release-notes.html

Starting a Gradle Daemon, 1 stopped Daemon could not be reused, use --status for details
WARNING:: Please remove usages of `jcenter()` Maven repository from your build scripts and migrate your build to other Maven repositories.
This repository is deprecated and it will be shut down in the future.
See http://developer.android.com/r/tools/jcenter-end-of-service for more information.
Currently detected usages in: root project 'My Application', project ':app'
WARNING:: The specified Android SDK Build Tools version (30.0.0) is ignored, as it is below the minimum supported version (30.0.2) for Android Gradle Plugin 4.2.0.
Android SDK Build Tools 30.0.2 will be used.
To suppress this warning, remove "buildToolsVersion '30.0.0'" from your build.gradle file, as each version of the Android Gradle Plugin now has a default version of the build tools.

BUILD SUCCESSFUL in 17s
34 actionable tasks: 26 executed, 8 up-to-date

如果在执行 gradlew test 命令后没有看到加法运算的结果,这可能是因为测试方法 addition_isCorrect() 并未输出任何结果。通常情况下,单元测试方法中的断言语句会在测试失败时输出信息,但在测试成功时不会有显式的输出。因此,如果测试通过,你可能不会看到加法运算的结果。

如果你希望在测试通过时也能看到一些输出信息,可以在单元测试方法中添加一些打印语句,例如:

package com.example.myapplication;

import org.junit.Test;

import static org.junit.Assert.*;

/**
 * Example local unit test, which will execute on the development machine (host).
 *
 * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
 */
public class ExampleUnitTest {
    @Test
//    public void addition_isCorrect() {
//        assertEquals(4, 2 + 2);
//    }
    public void addition_isCorrect() {
        int result = 2 + 2;
        System.out.println("加法运算结果为:" + result);
        assertEquals(4, result);
    }

}




参考

https://blog.csdn.net/weixin_41194129/article/details/136290891?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22136290891%22%2C%22source%22%3A%22weixin_41194129%22%7D

  • 24
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

源代码杀手

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值