瀏覽代碼

[core] Set minimum Android API level to 21

Him188 2 年之前
父節點
當前提交
84d03c9a71

+ 2 - 0
buildSrc/src/main/kotlin/Versions.kt

@@ -58,6 +58,7 @@ object Versions {
 
     const val androidGradlePlugin = "7.3.1"
     const val android = "4.1.1.4"
+    const val androidxAnnotation = "1.6.0"
 
     const val shadow = "8.1.0"
 
@@ -334,6 +335,7 @@ const val `jetbrains-annotations` = "org.jetbrains:annotations:19.0.0"
 
 const val `caller-finder` = "io.github.karlatemp:caller:1.1.1"
 
+const val `androidx-annotation` = "androidx.annotation:annotation:${Versions.androidxAnnotation}"
 const val `android-runtime` = "com.google.android:android:${Versions.android}"
 const val `netty-all` = "io.netty:netty-all:${Versions.netty}"
 const val `netty-handler` = "io.netty:netty-handler:${Versions.netty}"

+ 5 - 3
docs/Preparations.md

@@ -5,7 +5,9 @@
 ## JVM 环境要求
 
 - 桌面 JVM:最低 Java 8,但推荐 Java 11(要使用一键启动器,需要 11)
-- Android:Android SDK 26+ (Android 8.0,Oreo)
+- Android:
+    - mirai 2.15.0 起: API 等级 21 (Android 5.0,LOLLIPOP)
+    - mirai 2.15.0 前: API 等级 26 (Android 8.0,O)
 
 目前主要使用的自动启动器,[Mirai Console Loader](https://github.com/iTXTech/mirai-console-loader)
 ,(MCL) 默认安装 JRE 17。但旧版本 MCL 会默认安装 JRE 11。因此 Mirai Console 插件使用 JDK 11
@@ -36,8 +38,8 @@
 或 [Android Studio](https://developer.android.com/studio)。Mirai 提供 IDE
 插件来提升开发体验。
 
-|          插件名           |                         描述                         |               一键安装                |         JetBrains 插件仓库          |
-|:------------------------:|:---------------------------------------------------:|:-----------------------------------:|:----------------------------------:|
+|           插件名            |                     描述                     |               一键安装                |          JetBrains 插件仓库          |
+|:------------------------:|:------------------------------------------:|:---------------------------------:|:--------------------------------:|
 | [Mirai Console IntelliJ] | 提供 mirai-core 的错误检查和 mirai-console 的插件开发辅助 | [一键安装][Mirai Console IntelliJ-OK] | [说明页][Mirai Console IntelliJ-JB] |
 
 <!--| [Kotlin Jvm Blocking Bridge] |         帮助 Java 用户调用 Kotlin suspend 函数         | [Kotlin Jvm Blocking Bridge-OK] | [Kotlin Jvm Blocking Bridge-JB] |-->

+ 1 - 2
gradle.properties

@@ -16,8 +16,7 @@ kotlin.native.binary.memoryModel=experimental
 #kotlin.mpp.enableCompatibilityMetadataVariant=true
 systemProp.org.gradle.internal.publish.checksums.insecure=true
 gnsp.disableApplyOnlyOnRootProjectEnforcement=true
-# We may target 15 with Kotlin 1.5 IR
-mirai.android.target.api.level=26
+mirai.android.target.api.level=21
 # Enable if you want to use mavenLocal for both Gradle plugin and project dependencies resolutions.
 systemProp.use.maven.local=false
 org.gradle.caching=true

+ 6 - 0
mirai-core-utils/build.gradle.kts

@@ -65,6 +65,12 @@ kotlin {
             }
         }
 
+        findByName("androidMain")?.apply {
+            dependencies {
+                implementation(`androidx-annotation`)
+            }
+        }
+
         findByName("jvmMain")?.apply {
 
         }

+ 18 - 3
mirai-core-utils/src/androidMain/kotlin/Actuals.kt

@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
+ * Copyright 2019-2023 Mamoe Technologies and contributors.
  *
  * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
  * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@@ -8,11 +8,12 @@
  */
 
 @file:JvmMultifileClass
-@file:Suppress("NOTHING_TO_INLINE")
 
 package net.mamoe.mirai.utils
 
+import android.os.Build
 import android.util.Base64
+import androidx.annotation.RequiresApi
 
 
 public actual fun ByteArray.encodeBase64(): String {
@@ -23,6 +24,7 @@ public actual fun String.decodeBase64(): ByteArray {
     return Base64.decode(this, Base64.DEFAULT)
 }
 
+@RequiresApi(Build.VERSION_CODES.N)
 @PublishedApi
 internal class StacktraceException(override val message: String?, private val stacktrace: Array<StackTraceElement>) :
     Exception(message, null, true, false) {
@@ -30,10 +32,23 @@ internal class StacktraceException(override val message: String?, private val st
     override fun getStackTrace(): Array<StackTraceElement> = stacktrace
 }
 
+@PublishedApi
+internal class StacktraceExceptionBeforeN(
+    override val message: String?,
+    private val stacktrace: Array<StackTraceElement>
+) : Exception(message, null) {
+    override fun fillInStackTrace(): Throwable = this
+    override fun getStackTrace(): Array<StackTraceElement> = stacktrace
+}
+
 public actual inline fun <reified E> Throwable.unwrap(addSuppressed: Boolean): Throwable {
     if (this !is E) return this
     return if (addSuppressed) {
-        val e = StacktraceException("Unwrapped exception: $this", this.stackTrace)
+        val e = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+            StacktraceException("Unwrapped exception: $this", this.stackTrace)
+        } else {
+            StacktraceExceptionBeforeN("Unwrapped exception: $this", this.stackTrace)
+        }
         for (throwable in this.suppressed) {
             e.addSuppressed(throwable)
         }

+ 3 - 3
mirai-core/src/jvmBaseTest/kotlin/testFramework/desensitizer/Desensitizer.kt

@@ -1,5 +1,5 @@
 /*
- * Copyright 2019-2022 Mamoe Technologies and contributors.
+ * Copyright 2019-2023 Mamoe Technologies and contributors.
  *
  * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
  * Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
@@ -62,8 +62,8 @@ internal class Desensitizer private constructor(
 
                     val file: URL? =
                         File(filename).takeIf { it.isFile }?.toURI()?.toURL()
-                            ?: Thread.currentThread().contextClassLoader.getResource(filename)
-                            ?: Thread.currentThread().contextClassLoader.getResource("recording/configs/$filename")
+                            ?: Thread.currentThread().contextClassLoader?.getResource(filename)
+                            ?: Thread.currentThread().contextClassLoader?.getResource("recording/configs/$filename")
 
                     file?.readText()?.let { format.decodeFromString(it) } ?: kotlin.run {
                         logger.warning { "Couldn't find desensitization rules. You can set by system property 'mirai.network.recording.desensitization.filepath' to path to the desensitization configuration file, or use the 'local.desensitization.yml' by default." }