在整个应用程序中处理多个实验性注释
Handling multiple experimental annotations throughout an app
我有一个应用程序大量使用 Jetpack Compose 的实验性功能,所以我必须在可组合项上声明一堆注释。由于这些注释要求调用者也声明它们,所以我最终遇到了 activity 和以下代码的情况:
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.ui.ExperimentalComposeUiApi
import com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi
import com.google.accompanist.pager.ExperimentalPagerApi
import com.google.accompanist.permissions.ExperimentalPermissionsApi
…
class MainActivity : AppCompatActivity() {
@ExperimentalPermissionsApi
@ExperimentalComposeUiApi
@ExperimentalPagerApi
@ExperimentalMaterialNavigationApi
@ExperimentalMaterialApi
override fun onCreate(savedInstanceState: Bundle?) {
// … wiring up compose code (which propagates the experimental annotations)
避免这种情况的另一种方法是使用 @OptIn
代替,但由于每个声明只允许一个,所以它不适用于我的具有多个实验性功能的情况。
无论如何……这很好用——在 Kotlin 1.5 中。
使用 Kotlin 1.6 我遇到编译错误:
Opt-in requirement marker annotation on override requires the same marker on base declaration
但基础声明在标准 API 中,我无法更改。
我怎样才能编译(并像以前一样工作)?
我厌倦了我的代码被所有这些注释污染了。摆脱它们并编译代码的最简单方法就是将其添加到顶部 build.gradle 文件中 - 这并不详尽。只需为您需要的每个注释添加更多编译器参数:
allprojects {
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
freeCompilerArgs += [
"-Xuse-experimental=kotlin.ExperimentalUnsignedTypes",
"-Xuse-experimental=kotlinx.coroutines.ExperimentalCoroutinesApi",
"-Xuse-experimental=kotlinx.coroutines.InternalCoroutinesApi",
"-Xuse-experimental=androidx.compose.animation.ExperimentalAnimationApi",
"-Xuse-experimental=androidx.compose.ExperimentalComposeApi",
"-Xuse-experimental=androidx.compose.material.ExperimentalMaterialApi",
"-Xuse-experimental=androidx.compose.runtime.ExperimentalComposeApi",
"-Xuse-experimental=androidx.compose.ui.ExperimentalComposeUiApi",
"-Xuse-experimental=coil.annotation.ExperimentalCoilApi",
"-Xuse-experimental=kotlinx.serialization.ExperimentalSerializationApi",
"-Xuse-experimental=com.google.accompanist.pager.ExperimentalPagerApi"
]
}
}
}
Kotlin DSL 中 @Johanns 的一个未弃用的变体(带有我正在使用的一些其他注释):
弃用警告:
w: '-Xuse-experimental' is deprecated and will be removed in a future release, please use -opt-in instead
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile::class).all {
kotlinOptions {
freeCompilerArgs = freeCompilerArgs + listOf(
// Avoid having to stutter experimental annotations all over the codebase
"-Xopt-in=androidx.compose.animation.ExperimentalAnimationApi",
"-Xopt-in=androidx.compose.material.ExperimentalMaterialApi",
"-Xopt-in=androidx.compose.runtime.ExperimentalComposeApi",
"-Xopt-in=androidx.compose.ui.ExperimentalComposeUiApi",
"-Xopt-in=com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi",
"-Xopt-in=com.google.accompanist.pager.ExperimentalPagerApi",
"-Xopt-in=com.google.accompanist.permissions.ExperimentalPermissionsApi",
"-Xopt-in=kotlin.ExperimentalUnsignedTypes",
"-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
"-Xopt-in=kotlinx.coroutines.InternalCoroutinesApi"
)
}
}
An alternative to avoid this situation would be to use the @OptIn instead but since only one is allowed per declaration it doesn't work out for my case with multiple experimental features.
您可以将多个实验性特征用逗号分隔成 @OptIn
.
例如@OptIn(ExperimentalComposeUiApi::class, ExperimentalFoundationApi::class, ExperimentalMaterialApi::class)
TLDR;
@ExperimentalAnimationApi
❌
这个注释的意思是——“这是一个实验性的 API,所有用户都必须明确选择使用”。应用程序开发人员很少遇到这种情况。
@OptIn(ExperimetalAnimationApi::class)
✅
此注释的意思是 - “我选择使用实验性 api”。它不会强制此 method/class 的用户在他们的代码中添加注释。
问题
@ExperimentalAnimationApi
@Composable
fun MyCode()
表示MyCode
是实验性动画api,如果您想使用MyCode
,请明确选择加入ExperimentalAnimationApi
@Composable
fun MyOtherCode() {
MyCode() // ERROR!, doesn't compile and shows red underlines in IDE
}
通常会导致我们的代码中有太多 @ExperimentalAnimationApi
注释。 不要这样做
解决方案(修复编译,IDE 警告)
@OptIn(ExperimentalAnimationApi::class)
@Composable
fun MyCode() {
// experimental animation api usage
}
不会 强制调用者添加任何注释
@Composable
fun MyOtherCode() {
MyCode() // safe, compiles and doesn't show any errors in IDE
}
作为应用开发者,我们几乎总是要
使用 @OptIn(ExperimentalAnimationApi::class)
和
不 @ExperimentalAnimationApi
,
除非我们的代码本身在其 public 表面将实验性声明公开为 return 类型或函数参数等
仅修复编译的解决方案
或者我们可以添加
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
kotlinOptions {
freeCompilerArgs = freeCompilerArgs + listOf(
"-opt-in=androidx.compose.animation.ExperimentalAnimationApi",
)
}
}
但这不会删除 IDE 下划线等。所以不是很有用。
我有一个应用程序大量使用 Jetpack Compose 的实验性功能,所以我必须在可组合项上声明一堆注释。由于这些注释要求调用者也声明它们,所以我最终遇到了 activity 和以下代码的情况:
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.ui.ExperimentalComposeUiApi
import com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi
import com.google.accompanist.pager.ExperimentalPagerApi
import com.google.accompanist.permissions.ExperimentalPermissionsApi
…
class MainActivity : AppCompatActivity() {
@ExperimentalPermissionsApi
@ExperimentalComposeUiApi
@ExperimentalPagerApi
@ExperimentalMaterialNavigationApi
@ExperimentalMaterialApi
override fun onCreate(savedInstanceState: Bundle?) {
// … wiring up compose code (which propagates the experimental annotations)
避免这种情况的另一种方法是使用 @OptIn
代替,但由于每个声明只允许一个,所以它不适用于我的具有多个实验性功能的情况。
无论如何……这很好用——在 Kotlin 1.5 中。
使用 Kotlin 1.6 我遇到编译错误:
Opt-in requirement marker annotation on override requires the same marker on base declaration
但基础声明在标准 API 中,我无法更改。 我怎样才能编译(并像以前一样工作)?
我厌倦了我的代码被所有这些注释污染了。摆脱它们并编译代码的最简单方法就是将其添加到顶部 build.gradle 文件中 - 这并不详尽。只需为您需要的每个注释添加更多编译器参数:
allprojects {
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
freeCompilerArgs += [
"-Xuse-experimental=kotlin.ExperimentalUnsignedTypes",
"-Xuse-experimental=kotlinx.coroutines.ExperimentalCoroutinesApi",
"-Xuse-experimental=kotlinx.coroutines.InternalCoroutinesApi",
"-Xuse-experimental=androidx.compose.animation.ExperimentalAnimationApi",
"-Xuse-experimental=androidx.compose.ExperimentalComposeApi",
"-Xuse-experimental=androidx.compose.material.ExperimentalMaterialApi",
"-Xuse-experimental=androidx.compose.runtime.ExperimentalComposeApi",
"-Xuse-experimental=androidx.compose.ui.ExperimentalComposeUiApi",
"-Xuse-experimental=coil.annotation.ExperimentalCoilApi",
"-Xuse-experimental=kotlinx.serialization.ExperimentalSerializationApi",
"-Xuse-experimental=com.google.accompanist.pager.ExperimentalPagerApi"
]
}
}
}
Kotlin DSL 中 @Johanns
弃用警告:
w: '-Xuse-experimental' is deprecated and will be removed in a future release, please use -opt-in instead
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile::class).all {
kotlinOptions {
freeCompilerArgs = freeCompilerArgs + listOf(
// Avoid having to stutter experimental annotations all over the codebase
"-Xopt-in=androidx.compose.animation.ExperimentalAnimationApi",
"-Xopt-in=androidx.compose.material.ExperimentalMaterialApi",
"-Xopt-in=androidx.compose.runtime.ExperimentalComposeApi",
"-Xopt-in=androidx.compose.ui.ExperimentalComposeUiApi",
"-Xopt-in=com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi",
"-Xopt-in=com.google.accompanist.pager.ExperimentalPagerApi",
"-Xopt-in=com.google.accompanist.permissions.ExperimentalPermissionsApi",
"-Xopt-in=kotlin.ExperimentalUnsignedTypes",
"-Xopt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
"-Xopt-in=kotlinx.coroutines.InternalCoroutinesApi"
)
}
}
An alternative to avoid this situation would be to use the @OptIn instead but since only one is allowed per declaration it doesn't work out for my case with multiple experimental features.
您可以将多个实验性特征用逗号分隔成 @OptIn
.
例如@OptIn(ExperimentalComposeUiApi::class, ExperimentalFoundationApi::class, ExperimentalMaterialApi::class)
TLDR;
@ExperimentalAnimationApi
❌
这个注释的意思是——“这是一个实验性的 API,所有用户都必须明确选择使用”。应用程序开发人员很少遇到这种情况。
@OptIn(ExperimetalAnimationApi::class)
✅
此注释的意思是 - “我选择使用实验性 api”。它不会强制此 method/class 的用户在他们的代码中添加注释。
问题
@ExperimentalAnimationApi
@Composable
fun MyCode()
表示MyCode
是实验性动画api,如果您想使用MyCode
,请明确选择加入ExperimentalAnimationApi
@Composable
fun MyOtherCode() {
MyCode() // ERROR!, doesn't compile and shows red underlines in IDE
}
通常会导致我们的代码中有太多 @ExperimentalAnimationApi
注释。 不要这样做
解决方案(修复编译,IDE 警告)
@OptIn(ExperimentalAnimationApi::class)
@Composable
fun MyCode() {
// experimental animation api usage
}
不会 强制调用者添加任何注释
@Composable
fun MyOtherCode() {
MyCode() // safe, compiles and doesn't show any errors in IDE
}
作为应用开发者,我们几乎总是要
使用 @OptIn(ExperimentalAnimationApi::class)
和
不 @ExperimentalAnimationApi
,
除非我们的代码本身在其 public 表面将实验性声明公开为 return 类型或函数参数等
仅修复编译的解决方案
或者我们可以添加
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
kotlinOptions {
freeCompilerArgs = freeCompilerArgs + listOf(
"-opt-in=androidx.compose.animation.ExperimentalAnimationApi",
)
}
}
但这不会删除 IDE 下划线等。所以不是很有用。