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

news2024/12/21 11:02:52

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

目录

  • 一、项目文件
  • 二、详细解析
    • settings.gradle
    • local.properties
    • gradlew.bat(Windows运行脚本,可以不看)
    • gradlew
    • gradle.properties
    • build.gradle
    • \gradle\wrapper\gradle-wrapper.properties
    • proguard-rules.pro
    • app\build.gradle
    • \app\src\androidTest\java\com\example\myapplication\ExampleInstrumentedTest.java:package com.example.myapplication
    • \app\src\main\java\com\example\myapplication\MainActivity.java
    • \app\src\main\res
    • UI设计部分:ic_launcher_background
    • UI设计部分:ic_launcher_foreground
    • app\src\main\res\layout\activity_main.xml
    • \app\src\main\res\mipmap-anydpi-v26\ic_launcher.xml
    • app\src\main\AndroidManifest.xml
    • \app\src\test\java\com\example\myapplication\ExampleUnitTest.java
  • 参考

一、项目文件

项目文件剖析:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1487636.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SSM框架,SpringMVC框架的学习(上)

SpringMVC介绍 Spring Web MVC是基于Servlet API构建的原始Web框架&#xff0c;从一开始就包含在Spring Framework中。正式名称“Spring Web MVC”来自其源模块的名称&#xff08; spring-webmvc &#xff09;&#xff0c;但它通常被称为“Spring MVC”。 SpringMVC涉及组件 …

复合式统计图绘制方法(3)

复合式统计图绘制方法&#xff08;3&#xff09; 常用的统计图有条形图、柱形图、折线图、曲线图、饼图、环形图、扇形图。 前几类图比较容易绘制&#xff0c;饼图环形图绘制较难。 在统计图的应用方面&#xff0c;有时候有两个关联的统计学的样本值要用统计图来表达&#xff0…

Python电能质量扰动信号分类(六)基于扰动信号特征提取的超强机器学习识别模型

目录 往期精彩内容&#xff1a; 前言 1 数据集和特征提取 1.1 数据集导入 1.2 扰动信号特征提取 2超强模型XGBoost——原理介绍 2.1 原理介绍 2.2 特征数据集制作 3 模型评估和对比 3.1 随机森林分类模型 3.2 支持向量机SVM分类模型 3.3 XGBoost分类模型 代码、数据…

windows7怎么改ip地址?win7设置ip地址的步骤

随着网络的普及和技术的不断发展&#xff0c;IP地址对于计算机用户来说&#xff0c;已经不再是一个陌生的概念。在Windows 7操作系统中&#xff0c;根据网络环境和个人需求&#xff0c;有时我们需要手动修改IP地址。本文旨在向读者介绍如何在Windows 7系统中修改IP地址&#xf…

Redis常用指令,jedis与持久化

1.redis常用指令 第一个是key的常用指令&#xff0c;第二个是数据库的常用指令 前面的那些指令都是针对某一个数据类型操作的&#xff0c;现在的都是对所有的操作的 1.key常用指令 key应该设计哪些操作 key是一个字符串&#xff0c;通过key获取redis中保存的数据 对于key…

keil 中使用了cks32F103C8T6的芯片如何安装pack

首先是本来想使用stm32的芯片&#xff0c;结果商家给发过来的无法写入&#xff0c;一查是因为商家把cks的芯片给磨皮了&#xff0c;冒充stm来卖 那就花点时间来研究一下这个cks怎么在keil中写入 好不容易找到一个下载包 Keil.CS32F1xx_DFP.pack 【免费】中科芯CKSF103的PACK…

网络安全: Kali Linux 使用 hping3 阻塞目标主机

目录 一、实验 1.环境 2. 物理机测试远程连接 Windows server 3.Kali Linux 使⽤ hping3 ⼯具 二、问题 1. 常见的 DoS ⽅式有哪些 2.hping3 测试⼯具的命令格式和选项参数 一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 系统版本IP备注Kali Linux2024.…

Python实现向量自回归移动平均模型(VARMA算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 向量自回归移动平均模型&#xff08;Vector Autoregressive Moving Average, VARMA&#xff09;是一种…

在 Rust 中实现 TCP : 2.解析原始字节

解析原始字节 现在已经设置了虚拟网络接口并且它接收了数据位&#xff0c;实现 TCP 之旅的下一步是从接收到的数据字节中解析出数据包。默认情况下&#xff0c;除了从虚拟网络接口发送和接收的数据包之外&#xff0c;还会在数据包前面附加 4 个字节的数据。 Tun/TAP documenta…

Flutter混合栈管理方案对比

1.Google官方&#xff08;多引擎方案&#xff09; Google官方建议的方式是多引擎方案&#xff0c;即每次使用一个新的FlutterEngine来渲染Widget树&#xff0c;存在的主要问题是每个引擎都要有比较大的内存等资源消耗&#xff0c;虽然Flutter 2.0之后的FlutterEngineGroup通过在…

AI学习集合-前瞻

AI学习前瞻 工作岗位 算法工程师机器学习工程师图像算法工程师ai工程师NLP高级算法工程师 学习路线 应用场景 计算机视觉技术应用场景 自然语言应用 AI流程 AI拟人流程 机器人历史数据经验模型规律依据模型预测未来依据规律做出判断 AI基本流程 术语所用到的技术手段数据数…

收藏4款免费又好用的甘特图软件

zz-plan zz-plan&#xff08;https://zz-plan.com/&#xff09; 是一款基于甘特图的项目管理协作软件。无论项目大小、简单复杂都能轻松管理。任务、进度、工时、资源、周期、依赖关系都能一目了然。支持私有化部署&#xff0c;可完全控制、灵活定制、确保数据安全&#xff0c…

峟思测斜仪:工程斜坡稳定性的精确守护者

在工程建设领域&#xff0c;斜坡的稳定性始终是一个关键的安全问题。斜坡失稳不仅可能导致工程项目的延误&#xff0c;更可能威胁到人们的生命安全。为了有效监测和评估斜坡的稳定性&#xff0c;工程师们依赖于一种先进的设备——峟思测斜仪。 测斜仪的工作原理 峟思测斜仪采用…

分层解耦-IOCDI

内聚&#xff1a;软件中各个功能模块内部的功能联系。 耦合&#xff1a;衡量软件中各个层/模块之间依赖、关联的程度 软件设计原则&#xff1a;高内聚低耦合 控制反转&#xff1a;Inversion Of Control&#xff0c;简称IOC。对象的创建控制权由程序自身转移到外部&#xff08;…

c++ primer学习笔记(一)

目录 第一章、c快速入门 重点&#xff1a;类的简介 第二章 1、基本内置类型 2、字面值常量 1、整型字面值规则 2、浮点字面值规则 3、布尔字面值 4、字符字面值 5、非打印字符的转义序列 ​编辑 6、字符串字面值 3、变量 1、变量标识符 2、定义和初始化对象 3、…

javaWebssh网上超市销售管理系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 java ssh网上超市销售管理系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCA…

【深度学习笔记】计算机视觉——多尺度目标检测

多尺度目标检测 在 sec_anchor中&#xff0c;我们以输入图像的每个像素为中心&#xff0c;生成了多个锚框。 基本而言&#xff0c;这些锚框代表了图像不同区域的样本。 然而&#xff0c;如果为每个像素都生成的锚框&#xff0c;我们最终可能会得到太多需要计算的锚框。 想象一…

第十四届蓝桥杯大赛B组 JAVA 蜗牛 (递归剪枝)

题目描述&#xff1a; 这天&#xff0c;一只蜗牛来到了二维坐标系的原点。 在 x 轴上长有 n 根竹竿。它们平行于 y 轴&#xff0c;底部纵坐标为 0&#xff0c;横坐标分别为 x1, x2, …, xn。竹竿的高度均为无限高&#xff0c;宽度可忽略。蜗牛想要从原点走到第 n 个竹竿的底部也…

css样式元素的相对定位,绝对定位,固定定位等元素定位运用技巧详解

文章目录 1.相对定位 relative2.绝对定位 absolute3.固定定位4.display 转换元素5.float浮动6.float产生内容塌陷问题7.overflow CSS样式学习宝典&#xff0c;关注点赞加收藏&#xff0c;防止迷路哦 在CSS中关于定位的内容是&#xff1a;position:relative | absolute | static…

消防主机报故障时发出故障及原因及解决办法!

本文以青鸟消防JBF-11SF为例。 其他型号或品牌的消防主机也可参考。 开机前&#xff0c;必须先测量系统接线的绝缘电阻&#xff0c;确保各绝缘电阻满足以下要求&#xff1a; 1&#xff09;空载时各电路信号线之间的绝缘值应大于5K欧姆。 2&#xff09;正常天气条件下&#x…