- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开发一个 Kotlin 多平台应用程序,我想在我的模型类中使用 @Parcelize 注释。但是在 Kotlin Multiplatform 插件中,@Parcelize 注释在我使用的 kotlin 版本中是在 android.extensions 插件中,它适用于 androidApp 模块。
关于我的 build.gradle.kts(androidApp)
plugins {
id("com.android.application")
kotlin("android")
kotlin("android.extensions")
kotlin("kapt")
id("kotlinx-serialization")
id("androidx.navigation.safeargs.kotlin")
}
android {
compileSdkVersion(Versions.compileSdk)
compileOptions{
sourceCompatibility = org.gradle.api.JavaVersion.VERSION_1_8
targetCompatibility = org.gradle.api.JavaVersion.VERSION_1_8
}
kotlinOptions{
jvmTarget = JavaVersion.VERSION_1_8.toString()
}
kapt{
generateStubs = true
correctErrorTypes = true
}
androidExtensions{
isExperimental = true
}
buildFeatures{
dataBinding = true
viewBinding = true
}
defaultConfig {
applicationId = "com.jshvarts.kmp.android"
minSdkVersion(Versions.minSdk)
targetSdkVersion(Versions.targetSdk)
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
}
}
packagingOptions {
exclude("META-INF/*.kotlin_module")
}
}
dependencies {
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
implementation(kotlin("stdlib-jdk8", Versions.kotlin))
implementation(Coroutines.android)
implementation(AndroidX.appCompat)
implementation(AndroidX.constraintLayout)
implementation(AndroidX.recyclerView)
implementation(AndroidX.lifecycleExtensions)
implementation(AndroidX.lifecycleViewModelKtx)
implementation(material)
implementation(AndroidX.swipeToRefreshLayout)
implementation(timber)
implementation(picasso)
implementation(AndroidX.navigation)
implementation(AndroidX.navigation_ui)
implementation(Serialization.runtime)
//implementation(Serialization.core)
//Dependency for googlePay
implementation("com.google.android.gms:play-services-wallet:16.0.1")
kapt(databinding)
implementation(glide){
exclude( "com.android.support")
}
kapt(glide)
implementation(project(":shared"))
}
build.gradle.kts(共享)
plugins {
id("com.android.library")
kotlin("multiplatform")
kotlin("plugin.serialization")
//id("kotlinx-serialization")
id("org.jetbrains.kotlin.native.cocoapods")
id("com.squareup.sqldelight")
}
// CocoaPods requires the podspec to have a version.
version = "1.0"
android {
compileSdkVersion(Versions.compileSdk)
buildToolsVersion(Versions.androidBuildTools)
defaultConfig {
minSdkVersion(Versions.minSdk)
targetSdkVersion(Versions.targetSdk)
versionCode = 1
versionName = "1.0"
}
}
version = "1.0"
dependencies {
implementation("com.google.firebase:firebase-crashlytics-buildtools:2.8.1")
implementation(project(mapOf("path" to ":androidApp")))
}
kotlin {
targets {
val sdkName: String? = System.getenv("SDK_NAME")
val isiOSDevice = sdkName.orEmpty().startsWith("iphoneos")
if (isiOSDevice) {
iosArm64("iOS")
} else {
iosX64("iOS")
}
android()
}
cocoapods {
// Configure fields required by CocoaPods.
summary = "Description for a Kotlin/Native module"
homepage = "Link to a Kotlin/Native module homepage"
}
sourceSets {
all {
languageSettings.apply {
useExperimentalAnnotation("kotlinx.coroutines.ExperimentalCoroutinesApi")
}
}
val commonMain by getting {
dependencies {
implementation(kotlin("stdlib-common"))
implementation(Coroutines.Core.core)
implementation(Ktor.Core.common)
implementation(Ktor.Json.common)
implementation(Ktor.Logging.common)
implementation(Ktor.Serialization.common)
implementation(SqlDelight.runtime)
implementation(Serialization.runtime)
//implementation(project(":androidApp"))
//implementation("org.jetbrains.kotlin:kotlin-reflect:${Versions.kotlin}")
//implementation("org.jetbrains.kotlin:kotlin-reflect:${Versions.kotlin}")
//implementation ("org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.1")
}
}
val commonTest by getting {
dependencies {
implementation(Ktor.Mock.jvm)
}
}
val androidMain by getting {
dependencies {
implementation(kotlin("stdlib"))
implementation(Coroutines.Core.core)
implementation(Ktor.android)
implementation(Ktor.Core.jvm)
implementation(Ktor.Json.jvm)
implementation(Ktor.Logging.jvm)
implementation(Ktor.Logging.slf4j)
implementation(Ktor.Mock.jvm)
implementation(Ktor.Serialization.jvm)
implementation(Serialization.runtime)
//implementation(Serialization.core)
implementation(SqlDelight.android)
}
}
val androidTest by getting {
dependencies {
implementation(kotlin("test-junit"))
implementation(Ktor.Mock.common)
}
}
val iOSMain by getting {
dependencies {
implementation(Coroutines.Core.core)
implementation(Ktor.ios)
implementation(Ktor.Core.common)
implementation(Ktor.Json.common)
implementation(Ktor.Logging.common)
implementation(Ktor.Serialization.jvm)
// implementation(Serialization.runtimeNative)
implementation(SqlDelight.runtime)
implementation(Ktor.Mock.common)
}
}
val iOSTest by getting {
dependencies {
implementation(Ktor.Mock.native)
}
}
}
}
sqldelight {
database("PetsDatabase") {
packageName = "com.jshvarts.kmp.db"
sourceFolders = listOf("sqldelight")
}
}
还有我的项目build.gradle.kts
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
mavenCentral()
jcenter()
}
dependencies {
classpath("com.android.tools.build:gradle:4.0.0")
classpath(kotlin("gradle-plugin", version = Versions.kotlin))
classpath(kotlin("serialization", version = Versions.kotlin))
classpath("com.squareup.sqldelight:gradle-plugin:${Versions.sqldelight}")
classpath("com.github.ben-manes:gradle-versions-plugin:0.28.0")
classpath ("androidx.navigation:navigation-safe-args-gradle-plugin:${Versions.navigation}")
classpath ("org.jetbrains.kotlin:kotlin-android-extensions-runtime:${Versions.kotlin}")
}
}
allprojects {
repositories {
google()
mavenCentral()
jcenter()
}
}
//TODO("Probar bajando a kotlin version 1.3.72, y habilitando el android-extensions")
plugins {
//kotlin("jvm") version "${Versions.kotlin}"
id("org.jlleitschuh.gradle.ktlint") version "9.2.1"
id ("com.github.ben-manes.versions") version "0.28.0"
//kotlin("android") version "${Versions.kotlin}" apply false
//id("org.jetbrains.kotlin.plugin.parcelize") version "${Versions.kotlin}"
}
apply(from = "quality/lint.gradle")
所以我在 androidApp 和共享模块中创建了一个期望的和实际的 Parcelable 和 Parcelize 类:
androidApp
actual typealias Parcelable = android.os.Parcelable
actual typealias Parcelize = kotlinx.android.parcel.Parcelize
在共享模块中
// Common Code
expect interface Parcelable
@UseExperimental(ExperimentalMultiplatform::class)
@OptionalExpectation
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.BINARY)
expect annotation class Parcelize()
所以在那些类中我收到以下错误:
In Parcelable(shared)
Expected interface 'Parcelable' has no actual declaration in module KmpMVVMGooglePay.shared for JVM
Expected interface 'Parcelable' has no actual declaration in module KmpMVVMGooglePay.shared.iOSMain for Native
在android类中:
Actual typealias 'Parcelable' has no corresponding expected declaration
Actual typealias 'Parcelize' has no corresponding expected declaration
那么我缺少关于实际/预期关键字行为的什么?
提前感谢您的帮助!
最佳答案
这些 fragment 向您展示了如何在 KMM 项目中为任何类型的类(包括原语)使用 Android Parcelable
。它展示了注释、接口(interface)、泛型、对象、@TypeParceler
、Parceler
、Parcelable
、Parcelize
、以及如何实现通用代码、iOS 和 Android 的各个平台。
当 Android 应用进入后台并且 Parceler 自动运行以保存状态时,这是防止崩溃所必需的代码。
在这个例子中,我想要的是 LocalDateTime 的非 native 可分包类作为示例非 native 可分包类。您可以使用任何类,只需更改实现即可。
在 build.gradle.kts
(:shared)
plugins {
kotlin("multiplatform")
id("com.android.library")
id("kotlin-parcelize") // add this
id("kotlin-kapt") // add this
// ...rest of defintions...
}
kotlin {
android()
listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach {
it.binaries.framework {
baseName = "shared"
}
}
sourceSets {
val commonMain by getting {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0") // LocalDateTime library written in Kotlin (can't use java libraries)
}
}
// ...rest of definitions...
}
// ...rest of definitions...
}
在 commonMain/.../Platform.kt
import kotlinx.datetime.LocalDateTime
// For Android @Parcelize
@OptIn(ExperimentalMultiplatform::class)
@OptionalExpectation
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.BINARY)
expect annotation class CommonParcelize()
// For Android Parcelable
expect interface CommonParcelable
// For Android @TypeParceler
@OptIn(ExperimentalMultiplatform::class)
@OptionalExpectation
@Retention(AnnotationRetention.SOURCE)
@Repeatable
@Target(AnnotationTarget.CLASS, AnnotationTarget.PROPERTY)
expect annotation class CommonTypeParceler<T, P : CommonParceler<in T>>()
// For Android Parceler
expect interface CommonParceler<T>
// For Android @TypeParceler to convert LocalDateTime to Parcel
expect object LocalDateTimeParceler: CommonParceler<LocalDateTime>
在 androidMain/.../Platform.kt
重要提示:必须导入 kotlinx.parcelize.*
NOT kotlinx.android.parcel.*
import android.os.Parcel
import android.os.Parcelable
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.toLocalDateTime
import kotlinx.parcelize.Parceler
import kotlinx.parcelize.Parcelize
import kotlinx.parcelize.TypeParceler
actual typealias CommonParcelize = Parcelize
actual typealias CommonParcelable = Parcelable
actual typealias CommonParceler<T> = Parceler<T>
actual typealias CommonTypeParceler<T,P> = TypeParceler<T, P>
actual object LocalDateTimeParceler : Parceler<LocalDateTime> {
override fun create(parcel: Parcel): LocalDateTime {
val date = parcel.readString()
return date?.toLocalDateTime()
?: LocalDateTime(0, 0, 0, 0, 0)
}
override fun LocalDateTime.write(parcel: Parcel, flags: Int) {
parcel.writeString(this.toString())
}
}
在 iosMain/.../Platform.kt
import kotlinx.datetime.LocalDateTime
// Note: no need to define CommonParcelize here (bc its @OptionalExpectation)
actual interface CommonParcelable // not used on iOS
// Note: no need to define CommonTypeParceler<T,P : CommonParceler<in T>> here (bc its @OptionalExpectation)
actual interface CommonParceler<T> // not used on iOS
actual object LocalDateTimeParceler : CommonParceler<LocalDateTime> // not used on iOS
在 ../shared/commonMain/.../domain/note/Note.kt
这是您的域类,将由 iOS 和 Android 共享
import kotlinx.datetime.LocalDateTime
@CommonParcelize
data class Note(
val id: Long?,
val title: String,
val content: String,
val colorHex: Long,
@CommonTypeParceler<LocalDateTime, LocalDateTimeParceler>()
val created: LocalDateTime,
): CommonParcelable {
companion object {
private val colors = listOf(RedOrangeHex, RedPinkHex, LightGreenHex, BabyBlueHex, VioletHex)
fun generateRandomColor() = colors.random()
}
}
我尝试实现 @RawValue
但它没有记录(AFAIK)并且上述使用 @TypeParcelers
的方法对任何特定类都非常有效。我把它留给其他人作为练习!
关于android - Kotlin Multiplatform Project的共享模块中如何使用@Parcelize注解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70916976/
注解@CrossOrigin 出于安全原因,浏览器禁止Ajax调用驻留在当前原点之外的资源。例如,当你在一个标签中检查你的银行账户时,你可以在另一个选项卡上拥有EVILL网站。来自EVILL的脚本
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界. 这篇CFSDN的博客文章深入理解Java高级特性——注解由作者收集整理,如果你对这篇文章有兴趣,
概述 在这个快速教程中,我们将探索 Spring 的 @RequestParam 注解。 简单地说,我们可以使用 @RequestParam 从请求中提取查询参数、表单参数甚至文件。我们将讨论如何使用
我有一个关于 Spring @Async 注释的问题。我有一个 Controller 自动连接了一个服务(GnInsuranceDetailsService) @RequestMapping(va
我在使用注释来调用注释所属的方法时遇到了一些麻烦......我将举一个例子: class MyEventHandlers { @handler(id=“1”) public doSom
我是.Net程序员,但是这次我正在从事Java项目,并且遇到了一些困难。这个 java 项目不是我的,它是由其他开发人员开发的,并且使用 Hibernate。 当我运行 Ant 构建器时,我收到此错误
我在 Grails 文档(第 9 章:测试)中读到过这个注解。但是我不明白这是什么... 问题是我需要模拟 GORM 的动态方法,有一种方法可以自动模拟它们,而不必编写我需要的所有方法吗? 最佳答案
这个问题在这里已经有了答案: How to get annotation class name, attribute values using reflection (2 个答案) 关闭 5 年前。
如何了解 Java EE 6 JMS 注释规范支持的所有有效属性集@ActivationConfigProperty Java EE 6 Documentation for @ActivationCo
我认为这是不可能的,但也许我错了。所以我问你,如果可能的话。 ;-) 如果我定义了一个注释,它只接受类引用,它扩展了一些可能的接口(interface)或类: Class serviceIFProv
我正在尝试使用 javax.validation 验证一些 DTO,但似乎注释 @NotEmpty 没有检查参数是否为 null。 这是我的类(class): Person.class public
我是 hibernate 新手,我正在尝试学习它,但在尝试使一对多关系正常工作时遇到了问题。我尝试了几个例子,但似乎没有一个起作用。 有人可以看一下下面的代码并告诉我哪里出了问题吗?我尝试了很多不同的
这个问题已经有答案了: Why doesn't Java offer operator overloading? (17 个回答) 已关闭 9 年前。 每个人都知道 Java 中的简单算术如何用于基元
有人知道如何用 Python 处理这种 XML 注释,这是我第一次看到。 <?link id="752760" resource-uuid="UUID-9f0575a3-1847-1cde-fd
我遇到了这个link这解释了如何继承 bean。假设此示例中的 HelloWorld 类使用 @Component 注释作为 bean 公开,如何创建另一个继承此 bean 的 bean?我可以使用
谁能告诉我这段代码是否: public class OvTester { @Override public int hashCode() { return toStri
我有一个实体,它有一个非键列,我已将其设置为在我的数据库中自动生成。 我不能使用 @GeneratedValue,因为据我所知,它仅适用于关键字段。 在这种情况下,如何指示非键列是自动生成的? 最佳答
所以可能像很多人一样,我通常会临时注释掉代码,主要是为了调试目的。我目前放了类似 **DEBUG** 或任何容易搜索的内容,但我认为让编译器在发现临时注释掉的代码时输出警告(甚至错误)可能很有用。我想
此组件解决的问题是: 「谁」在「什么时间」对「什么」做了「什么事」 本组件目前针对 Spring-boot 做了 Autoconfig,如果是 SpringMVC,也可自己在 xml 初始化 b
配置全局乱码过滤器 参数绑定注解@RequestParam 注解@RequestParam的参数使用说明 获得Restful风格的参数 自定义类型转换器 自定义转换器的开发步骤: 获得Servlet相
我是一名优秀的程序员,十分优秀!