当前位置:   article > 正文

android 项目 gradle 统一版本管理_gradle 版本

gradle 版本

目前的android开发为了减少编译时间,开发效率,大多都采用模块化,组件化的开发方式。采用这种方式不可避免的将会用到多个Library。 那么当我们协同开发时,如何处理每个人的版本统一呢?

当你的项目中 module 的数量超过一个甚至越来越多的时候,对 Gradle 依赖进行统一管理就变得重要起来,因为你不会想在升级一个三方依赖的版本后发现冲突,然后一个个打开各个 module 的 build.gradle 文件,找到你升级的那个依赖引用,重复的进行版本修改;

因此我们有了初步的优化方案:

  • 在项目根目录下创建 config.gradle 文件,在其中按照以下格式添加相关配置;
  1. ext {
  2. /**
  3. * module开关统一申明在此处
  4. * true: 表示作为一个模块
  5. * false: 表示作为独立程序,可单独运行
  6. */
  7. isModule_a = true
  8. isModule_b = true
  9. // isModule_Location = false
  10. // isModule_Login = false
  11. // isModule_Main = false
  12. // isModule_Personal = false
  13. // isModule_ProductDetail = false
  14. // isModule_ShoppingCar = false
  15. /**
  16. * 版本信息统一管理
  17. */
  18. android = [
  19. compileSdkVersion: 31,
  20. buildToolsVersion: "30.0.3",
  21. applicationId : "com.XXXX.XXXX",
  22. minSdkVersion : 24,
  23. targetSdkVersion : 31,//27以上的版本http请求 权限不允许
  24. versionCode : 1,
  25. versionName : "1.0.0"
  26. ]
  27. dependencies = [
  28. //basic
  29. "appcompat" : 'androidx.appcompat:appcompat:1.4.1',
  30. "material" : 'com.google.android.material:material:1.5.0',
  31. "constraintlayout" : 'androidx.constraintlayout:constraintlayout:2.1.3',
  32. "navigation-fragment" : 'androidx.navigation:navigation-fragment:2.4.1',
  33. "navigation-ui" : 'androidx.navigation:navigation-ui:2.4.1',
  34. //Rxjava
  35. "rxjava" : "io.reactivex.rxjava2:rxjava:2.1.6",
  36. "rxandroid" : "io.reactivex.rxjava2:rxandroid:2.0.1",
  37. "rxrelay" : "com.jakewharton.rxrelay2:rxrelay:2.0.0",
  38. /*Rx生命周期管理*/
  39. "rxlifecycle" : "com.trello.rxlifecycle2:rxlifecycle:2.2.0",
  40. "rxlifecycle-components": "com.trello.rxlifecycle2:rxlifecycle-components:2.2.0",
  41. //Retrofit
  42. "retrofit" : "com.squareup.retrofit2:retrofit:2.4.0",
  43. "retrofit-gson" : "com.squareup.retrofit2:converter-gson:2.4.0",
  44. "retrofit-adapter" : "com.squareup.retrofit2:adapter-rxjava2:2.4.0",
  45. "okhttp-log-interceptor": "com.squareup.okhttp3:logging-interceptor:3.10.0",
  46. "okhttp3" : "com.squareup.okhttp3:okhttp:3.10.0",
  47. "gson" : "com.google.code.gson:gson:2.8.2",
  48. "logger" : "com.orhanobut:logger:2.1.1",
  49. //butterknife
  50. "butterknife" : "com.jakewharton:butterknife:10.1.0",
  51. "butterknife-anno" : "com.jakewharton:butterknife-compiler:10.1.0",
  52. /*eventBus*/
  53. "eventBus" : "org.greenrobot:eventbus:3.1.1",
  54. //room
  55. "room" : "androidx.room:room-runtime:2.2.5",
  56. "room-anno" : "androidx.room:room-compiler:2.2.5",
  57. "room-rxjava2" : "androidx.room:room-rxjava2:2.2.5", // 如果需要用到 rxjava
  58. "room-guava" : "androidx.room:room-guava:2.2.5",// 如果需要用到 guava
  59. "room-testing" : "androidx.room:room-testing:2.2.5",//需要用到相关测试工具的话
  60. //cameraX
  61. "camerax-core" : "androidx.camera:camera-camera2:1.0.0-beta06",//CameraX 核心库
  62. "camerax-lifecycle" : "androidx.camera:camera-lifecycle:1.0.0-beta06",// CameraX 生命周期
  63. "camerax-view" : "androidx.camera:camera-view:1.0.0-alpha10", //CameraX view 集合,比如 cameraview,preview等
  64. //Glide 4.11.0 才适配AndroidX
  65. "Glide" : "com.github.bumptech.glide:glide:4.11.0",
  66. "Glide-anno" : "com.github.bumptech.glide:compiler:4.11.0",
  67. //腾讯buggly
  68. "TecentBugly" : "com.tencent.bugly:crashreport:latest.release",
  69. "TecentBugly-native" : "com.tencent.bugly:nativecrashreport:latest.release",
  70. // 屏幕适配集成
  71. "Screen-Adapter" : "me.jessyan:autosize:1.2.1",
  72. //组件化 Arouter
  73. "Arouter" : "com.alibaba:arouter-api:1.2.2",
  74. "Arouter-anno" : "com.alibaba:arouter-compiler:1.1.3"
  75. ]
  76. avcProtocol = [
  77. "innerNet": "ws://",//ws
  78. "extraNet": "wss://"
  79. ]
  80. url = [
  81. // "debug" : "https://XXXXX.XXXXX.cn",//
  82. // "debug" : "http://192.168.71.126",//
  83. ]
  84. port = [
  85. // // "debug_port" : 53073 ,//avc
  86. ]
  87. filefolder = [
  88. "release_root_folder": "",
  89. "debug_root_folder" : "_debug"
  90. ]
  91. }
  • 在项目根目录下的 build.gradle 文件顶部添加 apply from: "config.gradle"

gradle 7.0 之前

  1. // Top-level build file where you can add configuration options common to all sub-projects/modules.
  2. println "----- RootGradle Start -----"
  3. apply from: "${rootProject.getRootDir()}/config.gradle"
  4. println "RootGradle ext path--->"+"${rootProject.getRootDir()}/config.gradle"
  5. buildscript {
  6. repositories {
  7. google()
  8. mavenCentral()
  9. }
  10. dependencies {
  11. classpath "com.android.tools.build:gradle:4.1.0"
  12. // NOTE: Do not place your application dependencies here; they belong
  13. // in the individual module build.gradle files
  14. }
  15. }
  16. task clean(type: Delete) {
  17. delete rootProject.buildDir
  18. }

gradle 7.0之后

  1. // Top-level build file where you can add configuration options common to all sub-projects/modules.
  2. plugins {
  3. id 'com.android.application' version '7.2.2' apply false
  4. id 'com.android.library' version '7.2.2' apply false
  5. id 'org.jetbrains.kotlin.android' version '1.6.10' apply false
  6. }
  7. apply from: this.rootProject.file('config.gradle')
  8. task clean(type: Delete) {
  9. delete rootProject.buildDir
  10. }

  • 在各个 module 的 build.gradle 中就可以通过 rootProject 来引用对应的依赖及参数了;

app 的build.gradle

  1. plugins {
  2. id 'com.android.application'
  3. }
  4. println "----- app Start -----"
  5. android {
  6. def versionConfig = rootProject.extensions.getByName("ext").android
  7. println "---app versionConfig is:" + versionConfig
  8. namespace 'com.demo.agreebankmvvm'
  9. compileSdk versionConfig.compileSdkVersion
  10. buildToolsVersion versionConfig.buildToolsVersion
  11. defaultConfig {
  12. applicationId "com.demo.agreebankmvvm"
  13. minSdk versionConfig.minSdkVersion
  14. targetSdk versionConfig.targetSdkVersion
  15. versionCode rootProject.ext.android["versionCode"]
  16. versionName rootProject.ext.android["versionName"]
  17. //版本名后面添加一句话,意思就是flavor dimension 它的维度就是该版本号,这样维度就是都是统一的了
  18. flavorDimensions "channel"
  19. //指定room.schemaLocation生成的文件路径
  20. javaCompileOptions {
  21. annotationProcessorOptions {
  22. arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
  23. }
  24. }
  25. //arouter
  26. javaCompileOptions {
  27. annotationProcessorOptions {
  28. arguments = [ moduleName : project.getName() ]
  29. }
  30. }
  31. }
  32. sourceSets {
  33. main {
  34. jniLibs.srcDirs = ['libs']
  35. }
  36. }
  37. signingConfigs {
  38. release {//发布版本的签名配置
  39. storeFile file(rootProject.RELEASE_KEYSTORE_FILE)
  40. keyAlias rootProject.RELEASE_KEY_ALIAS
  41. storePassword rootProject.RELEASE_KEYSTORE_PWD
  42. keyPassword rootProject.RELEASE_KEY_PWD
  43. }
  44. debug {//调试版本的签名配置
  45. storeFile file(rootProject.DEBUG_KEYSTORE_FILE)
  46. keyAlias rootProject.DEBUG_KEY_ALIAS
  47. storePassword rootProject.DEBUG_KEYSTORE_PWD
  48. keyPassword rootProject.DEBUG_KEY_PWD
  49. }
  50. }
  51. buildTypes {
  52. debug {
  53. File file = new File("${rootProject.getRootDir()}/jks/debugBank.jks")
  54. println "---debug signkey file is:" + file.exists()
  55. signingConfig signingConfigs.debug
  56. buildConfigField('String', 'PROJECT_ROOTFILE', "\"${filefolder["debug_root_folder"]}\"") //debug根文件夹名称
  57. buildConfigField('String', 'SERVER_URL', "\"${url["debug"]}\"")//配置debug的服务器地址
  58. buildConfigField('int', 'MESSAGE_URL_PORT', "${port["debug_port"]}") //配置debug模式下的服务器端口
  59. buildConfigField('String', 'avc_innerprotocol', "\"${avcProtocol["innerNet"]}\"") //配置debug模式下的协议内网(avc的初始化用)
  60. buildConfigField('String', 'avc_extraprotocol', "\"${avcProtocol["extraNet"]}\"") //配置debug模式下的协议外网(avc的初始化用)
  61. }
  62. release {
  63. minifyEnabled false
  64. proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
  65. File file = new File("${rootProject.getRootDir()}/jks/releaseBank.jks")
  66. println "---release signkey file is:" + file.exists()
  67. signingConfig signingConfigs.release
  68. buildConfigField('String', 'PROJECT_ROOTFILE', "\"${filefolder["release_root_folder"]}\"") //release根文件夹名称
  69. buildConfigField('String', 'SERVER_URL', "\"${url["release"]}\"")//配置release模式下的服务器地址
  70. buildConfigField('int', 'MESSAGE_URL_PORT', "${port["release_port"]}") //配置release模式下的服务器的端口
  71. buildConfigField('String', 'avc_extraprotocol', "\"${avcProtocol["extraNet"]}\"") //配置 release模式下的协议(avc的初始化用)
  72. }
  73. }
  74. compileOptions {
  75. sourceCompatibility JavaVersion.VERSION_1_8
  76. targetCompatibility JavaVersion.VERSION_1_8
  77. }
  78. //多渠道打包
  79. productFlavors {
  80. //juphone版本
  81. juPhonePHONE {
  82. buildConfigField('int', 'videoType', '0')
  83. buildConfigField('String', 'machineType', "\"phone\"" )
  84. buildConfigField('String', 'channelType', "\"C002\"" )
  85. applicationId "com.agree.bank.client_phone.phone"
  86. applicationIdSuffix ".juPhone"
  87. //替换清单文件中的标签
  88. manifestPlaceholders = [
  89. APP_ICON: "@mipmap/debug",
  90. APP_NAME: "phone-juPhone-BK",
  91. ]
  92. //versionName
  93. versionName "1.0.0"
  94. //versionCode
  95. versionCode 1
  96. }
  97. juPhonePAD {
  98. buildConfigField('int', 'videoType', '0')
  99. buildConfigField('String', 'machineType', "\"pad\"")
  100. buildConfigField('String', 'channelType', "\"C003\"" )
  101. applicationId "com.agree.bank.client_phone.pad"
  102. applicationIdSuffix ".juPhone"
  103. //替换清单文件中的标签
  104. manifestPlaceholders = [
  105. APP_ICON: "@mipmap/debug",
  106. APP_NAME: "pad-juPhone-BK",
  107. ]
  108. //versionName
  109. versionName "1.0.0"
  110. //versionCode
  111. versionCode 1
  112. }
  113. //avc版本
  114. AVCPHONE {
  115. buildConfigField('int', 'videoType', '1')
  116. buildConfigField('String', 'machineType', "\"phone\"" )
  117. buildConfigField('String', 'channelType', "\"C002\"" )
  118. applicationId "com.agree.bank.client_phone.phone"
  119. applicationIdSuffix ".AVC"
  120. //替换清单文件中的标签
  121. manifestPlaceholders = [
  122. APP_ICON: "@mipmap/ic_launcher_round",
  123. APP_NAME: "phone-AVC-BK",
  124. ]
  125. //versionName
  126. versionName "1.0.0"
  127. //versionCode
  128. versionCode 1
  129. }
  130. AVCPAD {
  131. buildConfigField('int', 'videoType', '1')
  132. buildConfigField('String', 'machineType', "\"pad\"")
  133. buildConfigField('String', 'channelType', "\"C003\"" )
  134. applicationId "com.agree.bank.client_phone.pad"
  135. applicationIdSuffix ".AVC"
  136. //替换清单文件中的标签
  137. manifestPlaceholders = [
  138. APP_ICON: "@mipmap/ic_launcher_round",
  139. APP_NAME: "pad-AVC-BK",
  140. ]
  141. //versionName
  142. versionName "1.0.0"
  143. //versionCode
  144. versionCode 1
  145. }
  146. //trtc版本
  147. TrtcPHONE {
  148. buildConfigField('int', 'videoType', '2')
  149. buildConfigField('String', 'machineType', "\"phone\"" )
  150. buildConfigField('String', 'channelType', "\"C002\"" )
  151. applicationId "com.agree.bank.client_phone.phone"
  152. applicationIdSuffix ".trtc"
  153. //替换清单文件中的标签
  154. manifestPlaceholders = [
  155. APP_ICON: "@mipmap/ic_launcher_round",
  156. APP_NAME: "phone-TRTC-BK",
  157. ]
  158. //versionName
  159. versionName "1.0.0"
  160. //versionCode
  161. versionCode 1
  162. }
  163. TrtcPAD {
  164. buildConfigField('int', 'videoType', '2')
  165. buildConfigField('String', 'machineType', "\"pad\"")
  166. buildConfigField('String', 'channelType', "\"C003\"" )
  167. applicationId "com.agree.bank.client_phone.pad"
  168. applicationIdSuffix ".trtc"
  169. //替换清单文件中的标签
  170. manifestPlaceholders = [
  171. APP_ICON: "@mipmap/ic_launcher_round",
  172. APP_NAME: "pad-TRTC-BK",
  173. ]
  174. //versionName
  175. versionName "1.0.0"
  176. //versionCode
  177. versionCode 1
  178. }
  179. }
  180. //打包重命名
  181. android.applicationVariants.all {
  182. variant ->
  183. variant.outputs.all {
  184. output -> output.outputFileName = "app" + "-PackTime" + new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC")) +"--" +buildType.name+ ".apk"
  185. }
  186. }
  187. //databinding
  188. buildFeatures.dataBinding = true
  189. }
  190. dependencies {
  191. // >基础依赖 - 其他模块需要可以单独依赖
  192. implementation project(':librarys:lib_basic')
  193. //ui_libary
  194. implementation project(':librarys:lib_ui')
  195. //pop_libary
  196. implementation project(':librarys:lib_pop')
  197. //net_libary
  198. implementation project(':librarys:lib_net')
  199. // 引入各个模块
  200. if (rootProject.ext.isModule_a) {
  201. implementation project(path: ':modules:module_a')
  202. }
  203. if (rootProject.ext.isModule_b) {
  204. implementation project(path: ':modules:module_b')
  205. }
  206. //retrofit
  207. implementation rootProject.ext.dependencies["retrofit"]
  208. implementation rootProject.ext.dependencies["retrofit-gson"]
  209. implementation rootProject.ext.dependencies["retrofit-adapter"]
  210. //okhttp
  211. implementation rootProject.ext.dependencies["okhttp-log-interceptor"]
  212. implementation rootProject.ext.dependencies["okhttp3"]
  213. // gson
  214. implementation rootProject.ext.dependencies["gson"]
  215. //room
  216. implementation rootProject.ext.dependencies["room"]
  217. annotationProcessor rootProject.ext.dependencies["room-anno"]
  218. implementation rootProject.ext.dependencies["room-rxjava2"]
  219. //arouter
  220. implementation rootProject.ext.dependencies["Arouter"]
  221. annotationProcessor rootProject.ext.dependencies["Arouter-anno"]
  222. }

App 的manifest.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools">
  4. <uses-permission android:name="android.permission.INTERNET"/>
  5. <application
  6. android:name="com.demo.agreebankmvvm.App"
  7. android:allowBackup="true"
  8. android:dataExtractionRules="@xml/data_extraction_rules"
  9. android:fullBackupContent="@xml/backup_rules"
  10. android:icon="@mipmap/ic_launcher"
  11. android:label="@string/app_name"
  12. android:roundIcon="@mipmap/ic_launcher_round"
  13. android:networkSecurityConfig="@xml/network_security_config"
  14. android:supportsRtl="true"
  15. android:theme="@style/Theme.AgreeBankMVVM"
  16. tools:targetApi="31">
  17. <activity android:name=".view.activity.TestBVMActivity"/>
  18. <activity android:name=".view.activity.TestBindActivity"/>
  19. <activity
  20. android:name=".view.activity.MainActivity"
  21. android:exported="true"
  22. android:label="@string/app_name"
  23. android:theme="@style/Theme.AgreeBankMVVM.NoActionBar">
  24. <intent-filter>
  25. <action android:name="android.intent.action.MAIN" />
  26. <category android:name="android.intent.category.LAUNCHER" />
  27. </intent-filter>
  28. <meta-data
  29. android:name="android.app.lib_name"
  30. android:value="" />
  31. </activity>
  32. </application>
  33. </manifest>

 

gradle.poroperties

  1. # Project-wide Gradle settings.
  2. # IDE (e.g. Android Studio) users:
  3. # Gradle settings configured through the IDE *will override*
  4. # any settings specified in this file.
  5. # For more details on how to configure your build environment visit
  6. # http://www.gradle.org/docs/current/userguide/build_environment.html
  7. # Specifies the JVM arguments used for the daemon process.
  8. # The setting is particularly useful for tweaking memory settings.
  9. org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
  10. # When configured, Gradle will run in incubating parallel mode.
  11. # This option should only be used with decoupled projects. More details, visit
  12. # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
  13. # org.gradle.parallel=true
  14. # AndroidX package structure to make it clearer which packages are bundled with the
  15. # Android operating system, and which are packaged with your app's APK
  16. # https://developer.android.com/topic/libraries/support-library/androidx-rn
  17. android.useAndroidX=true
  18. # Enables namespacing of each library's R class so that its R class includes only the
  19. # resources declared in the library itself and none from the library's dependencies,
  20. # thereby reducing the size of the R class for that library
  21. android.nonTransitiveRClass=true
  22. # Automatically convert third-party libraries to use AndroidX
  23. android.enableJetifier=true
  24. #test
  25. test = aaa
  26. ##########################################################################
  27. # debug ???? ??
  28. DEBUG_KEYSTORE_FILE = /../jks/debugBank.jks
  29. # release ???? ??
  30. RELEASE_KEYSTORE_FILE = /../jks/releaseBank.jks
  31. # debug ???????
  32. DEBUG_KEY_ALIAS = debugkey
  33. # release ???????
  34. RELEASE_KEY_ALIAS = releaseKey
  35. # debug keyStore ????? --> keyStorePassword
  36. DEBUG_KEYSTORE_PWD = 123456
  37. # debug ????? --> keyPassword
  38. DEBUG_KEY_PWD = 123456
  39. # release keyStore ????? --> keyStorePassword
  40. RELEASE_KEYSTORE_PWD = 123456
  41. # release ????? --> keyPassword
  42. RELEASE_KEY_PWD = 123456

module_a  的 build.gradle

  1. if (Boolean.valueOf(rootProject.ext.isModule_a)) {
  2. apply plugin: 'com.android.library'
  3. println "----- module_a Start as library-----"
  4. } else {
  5. apply plugin: 'com.android.application'
  6. println "----- module_a Start as application-----"
  7. }
  8. android {
  9. def versionConfig = rootProject.extensions.getByName("ext").android
  10. println "---module_a versionConfig is:" + versionConfig
  11. namespace 'com.demo.module_a'
  12. compileSdk versionConfig.compileSdkVersion
  13. buildToolsVersion versionConfig.buildToolsVersion
  14. defaultConfig {
  15. // 作为程序独立运行时才设置AppId
  16. if (!Boolean.valueOf(rootProject.ext.isModule_a)) {
  17. applicationId "com.demo.module_a"
  18. }
  19. minSdk versionConfig.minSdkVersion
  20. targetSdk versionConfig.targetSdkVersion
  21. versionCode rootProject.ext.android["versionCode"]
  22. versionName rootProject.ext.android["versionName"]
  23. testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
  24. //arouter
  25. javaCompileOptions {
  26. annotationProcessorOptions {
  27. arguments = [ moduleName : project.getName() ]
  28. }
  29. }
  30. }
  31. buildTypes {
  32. release {
  33. minifyEnabled false
  34. proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
  35. }
  36. }
  37. compileOptions {
  38. sourceCompatibility JavaVersion.VERSION_1_8
  39. targetCompatibility JavaVersion.VERSION_1_8
  40. }
  41. dataBinding {
  42. enabled = true
  43. }
  44. sourceSets {
  45. main {
  46. jniLibs.srcDirs = ['libs']
  47. if (!Boolean.valueOf(rootProject.ext.isModule_a)) {
  48. manifest.srcFile 'src/main/AndroidManifest.xml'
  49. } else {
  50. manifest.srcFile 'src/debug/AndroidManifest.xml'
  51. }
  52. }
  53. }
  54. }
  55. dependencies {
  56. // >基础依赖 - 其他模块需要可以单独依赖
  57. implementation project(':librarys:lib_basic')
  58. implementation fileTree(dir: 'libs', include: ['*.jar'])
  59. //arouter
  60. implementation rootProject.ext.dependencies["Arouter"]
  61. annotationProcessor rootProject.ext.dependencies["Arouter-anno"]
  62. }

module_a 的 main/manifest.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android">
  3. <application
  4. android:allowBackup="true"
  5. android:icon="@mipmap/ic_launcher"
  6. android:label="@string/app_name"
  7. android:roundIcon="@mipmap/ic_launcher_round"
  8. android:supportsRtl="true"
  9. android:theme="@style/Theme.AgreeBankMVVM">
  10. <activity
  11. android:name=".ModuleAMainActivity"
  12. android:exported="true">
  13. <intent-filter>
  14. <action android:name="android.intent.action.MAIN" />
  15. <category android:name="android.intent.category.LAUNCHER" />
  16. </intent-filter>
  17. <meta-data
  18. android:name="android.app.lib_name"
  19. android:value="" />
  20. </activity>
  21. </application>
  22. </manifest>

module_a 的 debug/manifest.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android">
  3. <application
  4. android:allowBackup="true"
  5. android:icon="@mipmap/ic_launcher"
  6. android:label="@string/app_name"
  7. android:roundIcon="@mipmap/ic_launcher_round"
  8. android:supportsRtl="true"
  9. android:theme="@style/Theme.AgreeBankMVVM">
  10. <activity
  11. android:name=".ModuleAMainActivity"
  12. android:exported="true">
  13. </activity>
  14. </application>
  15. </manifest>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/619044
推荐阅读
相关标签
  

闽ICP备14008679号