gpt4 book ai didi

kotlin - 带有私有(private)构造函数的分片密封类在从新事件中的 Intent 获取时会抛出无法访问的错误,但在其他地方都可以工作?

转载 作者:行者123 更新时间:2023-12-02 04:46:47 24 4
gpt4 key购买 nike

我创建了一个特殊的密封类来验证我的可为空 URL,这样我就可以安全、轻松地知道它的状态(无、无效、有效)

sealed class UrlType : Parcelable {
@Parcelize class Valid private constructor(val url: String) : UrlType() {
companion object : CompanionTest<UrlType.Valid, String>(::Valid)
}

@Parcelize object None : UrlType()
@Parcelize class Invalid(val invalidUrl: String) : UrlType()

companion object {

fun getUrlType(url: String?): UrlType {
return if (url == null) {
UrlType.None
} else if (!url.isValidUrl()) {
UrlType.Invalid(url)
} else {
Valid.create(url)
}
}
}
}
<小时/>
open class CompanionTest<out T, in A>(creator: (A) -> T) {

private var creator: ((A) -> T)? = creator

fun create(arg1: A): T {
return creator!!(arg1)
}
}
<小时/>
@Parcelize
data class NewsPost(
val id: String,
val title: String,
val description: String?,
val webContentUrl: UrlType,
val imageUrl: UrlType,
val created: String,
val updated: String,
val feeds: List<Feed>
) : Parcelable

当我第一次尝试这个想法时,我怀疑它不会工作,因为私有(private)构造函数和 Parcelize,但我做了一些测试,它确实工作了。

我还有一个密封类来指示我的事件的启动类型,可以从多个路径输入

sealed class NewsLaunchType : Parcelable {
@Parcelize object FeedList : NewsLaunchType()
@Parcelize class FeedDetail(val newsFeedType: NewsFeedType) : NewsLaunchType()
@Parcelize class PostDetail(val newsPost: NewsPost) : NewsLaunchType()
}

当我使用 NewsLaunchType.PostDetail(newsPost) 启动 Activity 时,应用程序崩溃并出现以下错误

fun startActivity(){
val intent = Intent(context, NewsActivity::class.java).apply {
putExtra("key", NewsLaunchType.PostDetail(newsPost))
}
startActivity(intent)
}
<小时/>
 override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContentView(R.layout.activity_news)

val newsActivityLaunchType = intent.getParcelableExtra<NewsLaunchType>("key")
}
<小时/>
2018-11-08 11:08:33.897 17030-17030/com.something.internal E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.something.internal, PID: 17030
java.lang.IllegalAccessError: Method 'void com.something.somethingkit.helper.UrlType$Valid.<init>(java.lang.String)' is inaccessible to class 'com.something.somethingkit.helper.UrlType$Valid$Creator' (declaration of 'com.something.somethingkit.helper.UrlType$Valid$Creator' appears in /data/app/com.something.internal-QTiupS4yw25rZK5uXP7UCQ==/base.apk:classes2.dex)
at com.something.somethingkit.helper.UrlType$Valid$Creator.createFromParcel(Unknown Source:11)
at android.os.Parcel.readParcelable(Parcel.java:2798)
at com.something.somethingkit.model.news.local.NewsPost$Creator.createFromParcel(Unknown Source:25)
at android.os.Parcel.readParcelable(Parcel.java:2798)
at com.something.screens.news.NewsLaunchType$PostDetail$Creator.createFromParcel(Unknown Source:13)
at android.os.Parcel.readParcelable(Parcel.java:2798)
at android.os.Parcel.readValue(Parcel.java:2692)
at android.os.Parcel.readArrayMapInternal(Parcel.java:3059)
at android.os.BaseBundle.unparcel(BaseBundle.java:257)
at android.os.Bundle.getParcelable(Bundle.java:888)
at android.content.Intent.getParcelableExtra(Intent.java:7734)
at com.something.screens.news.NewsActivity.onCreate(NewsActivity.kt:31)
at android.app.Activity.performCreate(Activity.java:7183)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1220)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2908)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3030)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6938)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

现在这并不完全出乎意料,只是如果我尝试将它拉出到我创建它的同一位置,它确实会起作用

 fun startActivity(){
val intent = Intent(context, NewsActivity::class.java).apply {
putExtra("key", NewsLaunchType.PostDetail(newsPost))
}

val test = intent.getParcelableExtra<NewsLaunchType>("key")
startActivity(intent)
}

如果我将其添加到片段包中,并将新片段添加/替换到我的事件中,它也可以工作。

companion object {
fun newInstance(newsPost: NewsPost): NewsDetailFragment {
val bundle = Bundle()
bundle.putParcelable(extraNewsPost, newsPost)

val fragment = NewsDetailFragment()
fragment.arguments = bundle
return fragment
}
}
<小时/>
 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val newsPost = arguments?.getParcelable<NewsPost>(extraNewsPost)

}

注意 - 当跨事件传递它时,会产生额外的密封类层,但如果我只是尝试跨事件传递 NewsPost,它也会崩溃,因此额外的层不是问题。

这似乎可能是 Kotlin Parcelize 功能的一个错误。

是否有任何原因可以解释为什么在事件之间传递它会引发错误,但在片段之间传递它却不会?如果有原因...关于如何在事件之间传递它有什么建议吗?

最佳答案

docs明确指出:

The primary constructor should be accessible (non-private)

不知道为什么它在传递到片段时起作用,而在传递到事件时不起作用。就我而言,我通过将类构造函数设置为内部来解决这个问题。

关于kotlin - 带有私有(private)构造函数的分片密封类在从新事件中的 Intent 获取时会抛出无法访问的错误,但在其他地方都可以工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53215095/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com