我有一个应用程序大量使用 Jetpack Compose 的实验功能,因此我必须在可组合项上声明一堆注释。由于这些注释要求调用者也声明它们,所以我最终遇到了以下情况:我有一个包含以下代码的活动:
\nimport androidx.appcompat.app.AppCompatActivity\n\nimport androidx.compose.material.ExperimentalMaterialApi\nimport androidx.compose.ui.ExperimentalComposeUiApi\n\nimport com.google.accompanist.navigation.material.ExperimentalMaterialNavigationApi\nimport com.google.accompanist.pager.ExperimentalPagerApi\nimport com.google.accompanist.permissions.ExperimentalPermissionsApi\n\xe2\x80\xa6\n\nclass MainActivity : AppCompatActivity() {\n\n @ExperimentalPermissionsApi\n @ExperimentalComposeUiApi\n @ExperimentalPagerApi\n @ExperimentalMaterialNavigationApi\n @ExperimentalMaterialApi\n override fun onCreate(savedInstanceState: Bundle?) {\n // \xe2\x80\xa6 wiring up compose code (which propagates the experimental annotations)\n
Run Code Online (Sandbox Code Playgroud)\n避免这种情况的另一种方法是使用@OptIn
,但由于每个声明只允许使用一个,因此它不适用于我的具有多个实验功能的情况。
无论如何\xe2\x80\xa6 这在 Kotlin 1.5 中 \xe2\x80\x94 工作得很好。
\n使用 Kotlin 1.6 我收到编译错误:
\n\n\n覆盖上的选择加入要求标记注释需要基本声明上的相同标记
\n
但基本声明位于标准 API 中,我无法更改。\n如何进行编译(并像以前一样工作)?
\n我正在尝试让 Room( https://developer.android.com/topic/libraries/architecture/room ) 与 Kotlin 的内联类一起工作,如Jake Whartons 文章内联类制作出色的数据库 ID 中所述:
@Entity
data class MyEntity(
@PrimaryKey val id: ID,
val title: String
)
inline class ID(val value: String)
Run Code Online (Sandbox Code Playgroud)
编译这个房间时抱怨说
实体和 Pojo 必须有一个可用的公共构造函数。您可以拥有一个空构造函数或一个其参数与字段(按名称和类型)匹配的构造函数。
查看生成的 Java 代码,我发现:
private MyEntity(String id, String title) {
this.id = id;
this.title = title;
}
// $FF: synthetic method
public MyEntity(String id, String title, DefaultConstructorMarker $constructor_marker) {
this(id, title);
}
Run Code Online (Sandbox Code Playgroud)
神秘的是,默认构造函数现在是私有的。
当String
用作id
( 或 a typealias
)的类型时,生成的 Java 类构造函数看起来像预期的那样: …
使用Kotlin为Android项目启用ProGuard时,Gradle构建失败,并显示以下错误:
警告:HomeChargerLocation:找不到引用的类kotlin.internal.annotations.AvoidUninitializedObjectCopyingCheck
警告:HomeChargerLocation $ Address:找不到引用的类kotlin.internal.annotations.AvoidUninitializedObjectCopyingCheck
警告:HomeChargerLocation $ Address $ Creator:找不到引用的类kotlin.internal.annotations.AvoidUninitializedObjectCopyingCheck
警告:HomeChargerLocation $ Car:找不到引用的类kotlin.internal.annotations.AvoidUninitializedObjectCopyingCheck
警告:HomeChargerLocation $ Car $ Creator:找不到引用的类kotlin.internal.annotations.AvoidUninitializedObjectCopyingCheck
警告:HomeChargerLocation $ Creator:找不到引用的类kotlin.internal.annotations.AvoidUninitializedObjectCopyingCheck
警告:处理任务java.io.IOException时发生异常:请先纠正上述警告.
相应的类:https://gist.github.com/makovkastar/cfa4bf1bea38556279f20eef46001cf8
我认为它与@Parcelize
Kotlin实验包中的注释有关,因为当我们开始使用它时问题出现了.
更新:我在Kotlin bug跟踪器中创建了一个问题 - https://youtrack.jetbrains.com/issue/KT-21628
我一直在尝试构建 React Native 应用程序,我一直在到处搜索,但无法解决这个问题。任何帮助或建议都将非常感激。
我的 Android 版本出现此错误:
/node_modules/react-native-gradle-plugin/src/main/kotlin/com/facebook/react/tasks/BundleHermesCTask.kt: (137, 11): This declaration is experimental and its usage must be marked with '@kotlin.ExperimentalStdlibApi' or '@OptIn(kotlin.ExperimentalStdlibApi::class)'
Run Code Online (Sandbox Code Playgroud)
在react-native-gradle-plugin中,我找到了文件BundleHermesCTask.kt。在此文件中,它向我显示此函数的错误,我可以将此行放在函数 @OptIn(ExperimentalStdlibApi::class) 之上,程序将构建并工作,但更改节点模块不是解决方案,因为它将被覆盖。
internal fun getBundleCommand(bundleFile: File, sourceMapFile: File): List<Any> =
windowsAwareCommandLine(
buildList {
addAll(nodeExecutableAndArgs.get())
add(cliFile.get().asFile.absolutePath)
add(bundleCommand.get())
add("--platform")
add("android")
add("--dev")
add(devEnabled.get().toString())
add("--reset-cache")
add("--entry-file")
add(entryFile.get().asFile.toString())
add("--bundle-output")
add(bundleFile.toString())
add("--assets-dest")
add(resourcesDir.get().asFile.toString())
add("--sourcemap-output")
add(sourceMapFile.toString())
if (bundleConfig.isPresent) {
add("--config")
add(bundleConfig.get().asFile.absolutePath)
}
add("--minify")
add(minifyEnabled.get().toString())
addAll(extraPackagerArgs.get())
add("--verbose")
})
Run Code Online (Sandbox Code Playgroud)
我在网上搜索并尝试了所有方法,从检查我的java版本到检查所有依赖项是否加载相同版本以及更新反应本机和依赖项。我唯一能做的就是更改文件 BundleHermesCTask.kt,但我无法执行此操作,因为构建过程将移动应用程序并执行 npm 安装所有依赖项,并且更改会丢失。
我已经检查了 github 页面,也一直在尝试了解 kotlin 有关 kotlin 的更多信息,并阅读
https://kotlinlang.org/docs/opt-in-requirements上的文档
我正在尝试@ExperimentalUnsignedTypes
在我的 AndroidStudio 项目中使用 。似乎我必须把它放在几乎任何地方,所以我宁愿在项目范围内设置它。
文档说
除非使用 UseExperimental 注释(例如 @UseExperimental(ExperimentalUnsignedTypes::class))或 -Xuse-experimental=kotlin.ExperimentalUnsignedTypes 编译器选项明确选择加入,否则此类 API 的使用将报告为警告。
尽职尽责地,我已经调整了我的Preferences>>Other Settings>>Kotlin Compiler
:
但是在清理/制作后我仍然收到(很多)警告。有人建议我也添加-XXLanguage:+InlineClasses
到同一行。但结果是一样的。然后我注意到在同一首选项窗格的顶部它说:
这是我的问题吗?如果是这样,我可以在哪里调整我的应用程序设置,以便这些编译器设置有效?
我试图理解内联类的概念-它们是在运行时内联的单一属性的简单对象包装。这意味着该类的实际初始化未在运行时发生
我正在尝试编写简单的测试,该测试将在JUnit测试期间直接显示我的上述解释,如下所示:
companion object {
private const val NAME = "JACK"
}
inline class NameInlineClass(val value: String)
@Test
fun unwrapping() {
val nameInlineClass = NameInlineClass(NAME)
val name = nameInlineClass
assertEquals(name, NAME)
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,该测试失败了,这使我assertEquals()
想到一个问题:为什么在实际的未包装的String值期间不进行比较,而在实际的内联类(运行时应对其进行包装)中不进行比较?