Android Studio 目录结构

参考:https://juejin.cn/post/6844903933584883720
参考:https://blog.csdn.net/Deep_rooted/article/details/124764731
参考:https://blog.csdn.net/delete_you/article/details/129126328

顶级结构

image.png

目录作用
.gradle自动生成的,Gradle编译系统,版本由wrapper指定
.idea自动生成的,Android Studio IDE所需要的文件
gradle这个目录下包含gradle wrapper的配置文件,使用gradle wrapper的方式不需要提前将gradle下载好,而是会自动根据本地的缓存情况决定是否需要联网下载gradle。
.gitignore上传git 忽略文件
build.gradle项目的gradle构建脚本,通常是不需要修改的
gradle.properties这个文件是全局的gradle文件,在这里配置的属性将会影响到项目中所有gradle编译的脚本。
gradlew用来在命令行界面执行 gradle命令的,gradlew是在Linux和Mac系统使用的
gradlew.bat用来在命令行界面执行 gradle命令的,gradlew.bat是在Windows系统使用的
local.properties本地配置,这个文件用于指定android SDK路径,通常是自动生成的,不需要修改
settings.gradle这个文件用于指定项目中引用的模块

.gitignore

git忽略文件,有些规则,稍微了解一下
#代表是写注释
忽略文件/目录
folderName:直接写名字,代表忽略所有目录和文件,而且会自动搜索多级目录下面的同名文件夹和名录。
folderName/:名字+斜杠结尾,代表忽略目录,不忽略同名的文件。
ps:注意一下,目录和文件的区别,目录就是文件夹,在git不允许空文件夹提交,所以不会有提交一个空文件的情况,而有些文件是没有后缀名的,所以可能出现目录和文件重名的情况。
如下的目录
如果是folder忽略,则是folder目录,以及src/folder 和 src/folder文件都会被忽略。
如果是folder/忽略,则只有folder目录忽略,而src/folder 和 src/folder文件不会被忽略

├── folder
│   └── file1
└── src
    ├── folder
    └── utils
        └── folder

/folderName:斜杠开头表示相对于这个.gitignore所在目录搜索,不会自动搜索多级目录。

!表示取反
!folderName:!代表反向操作,不忽略。

常用通配符
代表通配符,比如.log,代表匹配error.log,logs/debug.log等所有目录下以.log结尾的
代表匹配中间目录,比如src//build,可以匹配到src/test/build,也可以匹配到src/current/build。
?问号匹配 ‘/’外的单个任意字符,比如access?.log将会匹配access0.log,access1.log,accessA.log

gradle.properties

在使用Android Studio新建Android项目之后,在项目根目录下会默认生成一个gradle.properties文件,它是由IDE自动生成的gradle.properties文件。是项目级别的Gradle配置文件,gradle.properties里面定义的属性是全局的,可以在各个模块的build.gradle里面直接引用.我们可以在里面做一些Gradle文件的全局性的配置,也可以将比较私密的信息放在里面,防止泄露。
image.png
常用的的配置

org.gradle.jvmargs=-Xmx5120m -XX:MaxPermSize=1280m -Dfile.encoding=UTF-8
#(JVM堆内存大小,要是想运行的快一些,就改大点,整个8192m啥的)

 
android.useAndroidX=true
# 标识当前 module 启用 Androidx ,当把android项目自动迁移到androidX,
AS会自动在这个文件加上这句

android.enableJetifier=true
# 表示将项目中使用的第三方库也迁移到 Androidx
 
org.gradle.daemon=true
#通过开启守护进程,下一次构建的时候,将会连接这个守护进程进行构建,
#而不是重新 fork 一个 gradle构建进程
 
org.gradle.configureondemand=true 
#按需加载
 
org.gradle.parallel=true 
#并行编译
 
org.gradle.caching=true 
#开启 gradle 缓存
 
android.enableBuildCache=true
#开启依赖缓存,这个设置可以让Android Studio 会把依赖的 jar 或 arr 缓存到本地,并且把模块名称设置为 hash 值。每次编译生成的缓存在 $HOME/.android/build-cache

 
android.injected.testOnly=false
#解决真机无法安装测试包的报错,因为国内一些安卓手机制作商定制的 
#Android 系统不允许安装含带这个属性的测试包。哪怕你使用 -t 参数通过 adb 安装也是不行的,这个很常见
 
android.useNewApkCreator=false
#声明使用旧的打包器解决 Android Studio 升级 3.6 之后,
#报错 Entry name 'AndroidManifest.xml' collided,
#因此禁用新版本打包工具,使用旧的打包工具
 
kotlin.incremental=true
kotlin.incremental.java=true
kotlin.incremental.js=true
#kotlin 增量编译
 
kotlin.caching.enabled=true
#kotlin 编译缓存
 
kotlin.parallel.tasks.in.project=true
#kotlin 并行编译
 
kotlin.code.style=official
# Kotlin code style for this project: "official" or "obsolete"
 
 
# 优化kapt
# 并行运行kapt1.2.60版本以上支持
kapt.use.worker.api=true
# 增量编译 kapt1.3.30版本以上支持
kapt.incremental.apt=true
# kapt avoiding 如果用kapt依赖的内容没有变化,会完全重用编译内容,省掉#`app:kaptGenerateStubsDebugKotlin`的时间
kapt.include.compile.classpath=false
 

build.gradle

旧版本
项目的gradle构建脚本,分为buildscript{},allprojects{},task clean(type: Delete){}这三块

// buildScript gradle的构建脚本
buildscript {
    repositories {
        google()
        mavenCentral()
        jcenter()
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
    }
    dependencies {
    	// 指定gradle插件版本
        classpath "com.android.tools.build:gradle:4.2.2"
    }
}

// allprojects是对所有的项目配置
allprojects {
    repositories {
        google()
        mavenCentral()
        jcenter()
    }
}

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

  • **buildScript:**buildscript{}闭包里是gradle脚本执行所需依赖,分别是对应的maven库和插件。

buildscript中的声明是gradle脚本自身需要使用的资源。可以声明的资源包括依赖项、第三方插件、maven 仓库地址等,gradle在执行脚本时,会优先执行buildscript代码块中的内容,然后才会执行剩余的build脚本。

  • repositories:

代表仓库地址,常见参数:
google()“Google官方依赖存储库
mavencentral():由sonatype.org维护的Maven仓库
jcenter():由 bintray.com维护的Maven仓库
maven { url ‘http://maven.aliyun.com/nexus/content/groups/public/}:手动指定Maven仓库地址
JCenter() 与 mavenCenter()在完全不同的服务器上维护,由不同的人提供内容,两者之间毫无关系。在jcenter上有的可能 Maven Central 上没有,反之亦然

  • dependcies:

dependices闭包代表声明下载所需要的依赖,类似maven工程pom.xml中 标签
classpath
添加 buildscript 本身需要的依赖。
implementation
一般是在在模块中的build.gradle中,dependencies 中添加的使应用程序所需要的依赖包,也就是项目运行所需要的东西

  • **allprojects:**allprojects{}闭包里是项目本身需要的依赖,比如项目所需的maven库。是对所有项目声明的配置
    • repositories

声明所有项目声明的依赖仓库。和buildScript中意思相同。

  • **task clean(type: Delete){}:**是运行gradle clean时,执行此处定义的task任务,该任务继承自Delete,删除根目录中的build目录。其中buildscript包含repositories闭包和dependencies闭包。

新版本

plugins {
    id 'com.android.application' version '7.1.2' apply false
    id 'com.android.library' version '7.1.2' apply false
}

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

2022年1月的Gradle7.1.0版本做的更新,如果你用的是小蜜蜂版本的Android Studio,创建的的项目,默认就是没有buildscript和allprojects的,之前的仓库配置被挪到Project下的setting.gradle里面了。
如果确实还是需要旧版本的buildscript{}内容,还是可以使用,放在plugins{}上面即可,例如

buildscript {
    dependencies {
        classpath 'com.yanzhenjie.andserver:plugin:2.1.10'
    }
}

plugins {
    id 'com.android.application' version '7.1.2' apply false
    id 'com.android.library' version '7.1.2' apply false
}

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

local.properties

sdk.dir=AppData\Local\Android\Sdk
本地配置,这个文件用于指定android SDK路径,通常是自动生成的,不需要修改

seetings.gradle

存放于项目根目录下,此设置文件会定义项目级代码库设置,并告知 Gradle 在构建应用时应将哪些模块包含在内

// 依赖管理
// 定义远程或者本地仓库位置,gradle将会从这些仓库搜索并下载对应依赖以及相关内容
pluginManagement {

    // 定义仓库
    repositories {
        gradlePluginPortal()
        google()                // google官方仓库
        mavenCentral()          // maven中心仓库,替代老版本的JCenter
    }

    // 定义解决方案,即对所下载的依赖做出的处理
    resolutionStrategy{
        eachPlugin{
            if (requested.id.id == 'dagger.hilt.android.plugin'){
                useModule("com.google.dagger:hilt-android-gradle-plugin:2.38.1")
            }
        }
    }
}

// 定义所有模块的仓库位置
// 这是一项全局配置,对于单个模块仍然需要定义自己的build.gradle来设置!
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}

// 根工程名称(即你创建该android项目时的名字)
rootProject.name = "Character"
// 定义模块目录所在位置
include ':app'

rootProject:配置的是当前的工程名
include:引用不同的moulde

moudle(App)目录

image.png

目录作用
buidl编译时生成
libs存放第三方的jar包
release存放打包文件,需要打包完成才有的文件夹
srcmodule源码所在目录
.gitignoregit源码管理文件
proguard-rules.pro指定代码混淆
build.gradleapp模块的gradle构建脚本
app.imlintellij IDEA项目都会自动生成的,AS是基于IDEA开发的

build

和外层的build类似主要包含编译时自动生成的内容,其中在outputs文件夹下存放打包好的apk文件

libs

如果项目中是用了第三方的jar包,就需要把jar包放到libs目录下,然后jar包会被自动添加到构建路径(如集成百度地图sdk,把jar包放到libs目录。可以在build.gradle(app)文件中查看当前项目依赖)

release

存放打包文件,需要打包操作之后,选择路径才会生成

.gitignore

git源码管理文件,同最外层一样

proguard-rules.pro

指定混淆规则,需要和module的build.gradle里面android{}闭包里面buildTypes{}配合使用,是否打开混淆。(目前没有使用需求,后续补充)

build.gradle:

app模块的gradle构建脚本,总共有三块
image.png
apply:声明是Android程序
android:android{}闭包,这个闭包主要为了配置项目构建的各种属性
dependecies:dependencies{}闭包,该闭包定义了项目的依赖关系,一般项目都有三种依赖方式:本地依赖、库依赖和远程依赖。
大概build.gradle构建脚本如下

plugins {
    id 'com.android.application'
}

android {
    compileSdkVersion 33  // 编译Android工程的SDK版本
    buildToolsVersion "33.0.0" // 构建Android工程所用的构建工具版本,Android Studio3.0后去除此项配置
        
    defaultConfig {
        applicationId "com.example.gradle_lifecycle"
        minSdkVersion 21
        targetSdkVersion 33
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false //是否启用混淆
            // 混淆文件
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }

	//自动化打包配置
    signingConfigs {// 自动化打包配置
            release {// 线上环境
                keyAlias 'test'
                keyPassword '123456'
                storeFile file('test.keystore')
                storePassword '123456'
            }
            debug {// 开发环境
                keyAlias 'test'
                keyPassword '123456'
                storeFile file('test.keystore')
                storePassword '123456'
            }
        }
	
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
	// implemengtation 添加的使应用程序所需要的依赖包
    implementation 'androidx.appcompat:appcompat:1.5.1'
    implementation project(':mylibrary')
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
  • **plugins{}:**一般有两种值可选:

com.android.application 表示这是一个应用程序模块。可以直接运行。
com.android.library 表示这是一个库模块,只能作为代码库依附于别的应用程序模块来运行,打包得到的是.aar文件

  • **android{}:**android{}是Android Gradle插件提供的一个扩展类型,可以让我们自定义Android Gradle工程。
    • **compileSdkVersion:**编译Android工程的SDK版本
    • **buildToolsVersion “23.0.1”:**构建Android工程所用的构建工具版本
    • **defaultConfig{}:**defaultConfig{}是默认的配置,是一个ProductFlavor(构建渠道),ProductFlavor允许我们根据不同的情况同时生成不同的APK包。defaultConfig闭包可以对项目的更多细节进行配置。
defaultConfig {
        applicationId "com.example.gradle_lifecycle"
        minSdkVersion 21
        targetSdkVersion 33
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
  - **applicationId** :应用ID,在Android设备和市场上,这个ID是你应用的唯一标识。不是包名,默认和包名一致。
  - **midSdkVersion:**用于指定项目最低兼容的Android系统版本。midSdkVersion 21对应Android 5.0。表示安装应用程序的手机系统的版本必须要>=5.0
  - **targetSdkVersion:**APP所使用这个所设定的版本及该版本前的所有特性。如果设置为22,那么23以及23以后的所有新特性、新功能和API新行为统统无视;只认识22以及22之前提供的功能和API行为。
  - **versionCodeApp:**应用内部版本名称,自己看的,用来给设备程序识别版本。
  - **versionNameAPP:**应用的版本名称。展示给消费者的版本号,代表应用程序的版本信息。
  • **buildTypes{}:**生产/测试环境配置。
buildTypes {// 生产/测试环境配置
        release {// 生产环境
            buildConfigField("boolean", "LOG_DEBUG", "false")//配置Log日志
            buildConfigField("String", "URL_PERFIX", ""https://release.cn/"")// 配置URL前缀
            minifyEnabled false//是否对代码进行混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的规则文件
            signingConfig signingConfigs.release//设置签名信息
            pseudoLocalesEnabled false//是否在APK中生成伪语言环境,帮助国际化的东西,一般使用的不多
            zipAlignEnabled true//是否对APK包执行ZIP对齐优化,减小zip体积,增加运行效率
            applicationIdSuffix 'test'//在applicationId 中添加了一个后缀,一般使用的不多
            versionNameSuffix 'test'//在applicationId 中添加了一个后缀,一般使用的不多
        }
        debug {// 测试环境
            buildConfigField("boolean", "LOG_DEBUG", "true")//配置Log日志
            buildConfigField("String", "URL_PERFIX", ""https://test.com/"")// 配置URL前缀
            minifyEnabled false//是否对代码进行混淆
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'//指定混淆的规则文件
            signingConfig signingConfigs.debug//设置签名信息
            debuggable false//是否支持断点调试
            jniDebuggable false//是否可以调试NDK代码
            renderscriptDebuggable false//是否开启渲染脚本就是一些c写的渲染方法
            zipAlignEnabled true//是否对APK包执行ZIP对齐优化,减小zip体积,增加运行效率
            pseudoLocalesEnabled false//是否在APK中生成伪语言环境,帮助国际化的东西,一般使用的不多
            applicationIdSuffix 'test'//在applicationId 中添加了一个后缀,一般使用的不多
            versionNameSuffix 'test'//在applicationId 中添加了一个后缀,一般使用的不多
        }
    }
  - **release {}:** 生产环境
     - **minifyEnabled**:表明是否对代码进行混淆,true表示对代码进行混淆,false表示对代码不进行混淆,默认的是false。
     - **proguardFiles**:指定混淆的规则文件,这里指定了proguard-android.txt文件和proguard-rules.pro文件两个文件,proguard-android.txt文件为默认的混淆文件,里面定义了一些通用的混淆规则。proguard-rules.pro文件位于当前项目的根目录下,可以在该文件中定义一些项目特有的混淆规则。
     - **buildConfigField**:用于解决Beta版本服务和Release版本服务地址不同或者一些Log打印需求控制的。例如:配置buildConfigField("boolean", "LOG_DEBUG", "true"),这个方法接收三个非空的参数,第一个:确定值的类型,第二个:指定key的名字,第三个:传值,调用的时候BuildConfig.LOG_DEBUG即可调用。
     - **debuggable**:表示是否支持断点调试,release默认为false,debug默认为true。
     - **jniDebuggable**:表示是否可以调试NDK代码,使用lldb进行c和c++代码调试,release默认为false
     - **signingConfig**:设置签名信息,通过signingConfigs.release或者signingConfigs.debug,配置相应的签名,但是添加此配置前必须先添加signingConfigs闭包,添加相应的签名信息。
     - **renderscriptDebuggable**:表示是否开启渲染脚本就是一些c写的渲染方法,默认为false。
     - **renderscriptOptimLevel**:表示渲染等级,默认是3。
     - **pseudoLocalesEnabled**:是否在APK中生成伪语言环境,帮助国际化的东西,一般使用的不多。
     - **applicationIdSuffix**:和defaultConfig中配置是一的,这里是在applicationId 中添加了一个后缀,一般使用的不多。
     - **versionNameSuffix**:表示添加版本名称的后缀,一般使用的不多。
     - **zipAlignEnabled**:表示是否对APK包执行ZIP对齐优化,减小zip体积,增加运行效率,release和debug默认都为true。
  - **debug {}:**开发环境,关键参数同生产环境
  • **signingConfigs{}:**自动化打包配置
    signingConfigs {// 自动化打包配置
            release {// 线上环境
                keyAlias 'test'
                keyPassword '123456'
                storeFile file('test.keystore')
                storePassword '123456'
            }
            debug {// 开发环境
                keyAlias 'test'
                keyPassword '123456'
                storeFile file('test.keystore')
                storePassword '123456'
            }
        }
  - **release {}:**线上环境
     - keyAlias 'test':关键别名
     - keyPassword '123456' :关键别名密码
     - storeFile file('test.keystore') :位置
     - storePassword '123456' //密码
  - **debug {}:**开发环境,同线上环境
  • sourceSets{}:配置目录指向
    • 配置 jniLibs.srcDirs = [‘libs’],可以在Android studio的Android视图下生成jniLibs文件夹,可以方便我们存放jar包和库文件,其中Android视图下的jniLibs和project视图下的libs指向同一文件夹(app→libs),如下图所示:
sourceSets {//目录指向配置 
	main {
    jniLibs.srcDirs = ['libs']//指定lib库目录 
  } 
}
  • packagingOptions{}闭包:打包时的相关配置,当项目中依赖的第三方库越来越多时,有可能会出现两个依赖库中存在同一个(名称)文件。如果这样,Gradle在打包时就会提示错误(警告)。那么就可以根据提示,然后使用以下方法将重复的文件剔除,比较常用的是通过exclude去除重复的文件,例如:
packagingOptions{
        //pickFirsts做用是 当有重复文件时 打包会报错 这样配置会使用第一个匹配的文件打包进入apk
        // 表示当apk中有重复的META-INF目录下有重复的LICENSE文件时 只用第一个 这样打包就不会报错
        pickFirsts = ['META-INF/LICENSE']

        //merges何必 当出现重复文件时 合并重复的文件 然后打包入apk
        //这个是有默认值得 merges = [] 这样会把默默认值去掉 所以我们用下面这种方式 在默认值后添加
        merge 'META-INF/LICENSE'

        //这个是在同时使用butterknife、dagger2做的一个处理。同理,遇到类似的问题,只要根据gradle的提示,做类似处理即可。
        exclude 'META-INF/services/javax.annotation.processing.Processor'
    }

  • productFlavors{}:多个渠道配置这个配置是经常会使用到的,通常在适配多个渠道的时候,需要为特定的渠道做部分特殊的处理,比如设置不同的包名、应用名等。场景:当我们使用友盟统计时,通常需要设置一个渠道ID,那么我们就可以利用productFlavors来生成对应渠道信息的包,如:
productFlavors {
        wandoujia {
            //豌豆荚渠道包配置
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "wandoujia"]
            //manifestPlaceholders的使用在后续章节(AndroidManifest里的占位符)中介绍
        }
        xiaomi {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "xiaomi"]
            applicationId "com.wiky.gradle.xiaomi" //配置包名

        }
        _360 {
            manifestPlaceholders = [UMENG_CHANNEL_VALUE: "_360"]
        }
        //...
    } 
  • lintOptions{}:代码扫描分析,Lint 是Android Studio 提供的 代码扫描分析工具,它可以帮助我们发现代码结构/质量问题,同时提供一些解决方案,而且这个过程不需要我们手写测试用例。Lint 发现的每个问题都有描述信息和等级(和测试发现 bug 很相似),我们可以很方便地定位问题,同时按照严重程度进行解决。
	//程序在编译的时候会检查lint,有任何错误提示会停止build,我们可以关闭这个开关
    lintOptions {
        abortOnError false //即使报错也不会停止打包
        checkReleaseBuilds false  //打包release版本的时候进行检测
    }

  • **dependcies{}:**该闭包定义了项目的依赖关系,一般项目都有三种依赖方式:本地依赖、库依赖和远程依赖。本地依赖可以对本地的jar包或目录添加依赖关系,库依赖可以对项目中的库模块添加依赖关系,远程依赖可以对jcener库上的开源项目添加依赖关系。
    • 从Android Studio3.0后compile引入库不在使用,而是通过api和implementation,api完全等同于以前的compile,用api引入的库整个项目都可以使用,用implementation引入的库只有对应的Module能使用,其他Module不能使用,由于之前的项目统一用compile依赖,导致的情况就是模块耦合性太高,不利于项目拆解,使用implementation之后虽然使用起来复杂了但是做到降低偶合兴提高安全性。
dependencies {//项目的依赖关系
    implementation fileTree(include: ['*.jar'], dir: 'libs')//本地jar包依赖
    implementation 'com.android.support:appcompat-v7:27.1.1'//远程依赖
    implementation 'com.android.support.constraint:constraint-layout:1.1.2'
    testImplementation 'junit:junit:4.12'//声明测试用例库
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
  • implementation fileTree(include: [‘*.jar’], dir: ‘libs’):implementation fileTree是一个本地依赖声明,表示将libs目录下所有.jar后缀的文件都添加到项目的构建路径当中。
  • implementation ‘com.android.support:appcompat-v7:27.1.1’:implementation语句为 远程依赖声明,'com.android.support:appcompat-v7:27.1.1’为一个标准的远程依赖库格式,其中com.android.support为域名部分,用于区分不同公司的库;appcompat-v7为组件名称,用于区分同一个公司的不同库;27.1.1为版本号,用于区分同一个库的不同版本。加上这句声明后,Gradle在构建项目时会先检查一下本地是否已经缓存过该库,若没有缓存则自动联网下载,下载后自动添加到项目的构建路径中去。
  • testImplementation和androidTestImplementation:表示声明测试用例库。
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值