You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中对象字符串转数据类及Fragment间数据类传递方案

如何处理Fragment间数据类传递与toString转数据类的问题

首先得明确说清楚:直接把dataClass.toString()的结果转回数据类是非常不推荐的做法。因为toString()的输出是为了人类可读性设计的,没有统一的标准化格式——一旦你的数据类新增字段、修改字段顺序,或者系统默认的toString()实现有变化,你的解析逻辑就会直接崩溃,维护成本极高。

如果非要硬做,你得自己写解析逻辑,比如用正则表达式匹配每个字段的键值对,嵌套类还要递归解析,但这种方式完全是给自己挖坑,真心不建议。

更优的Fragment间数据类传递方式

Android官方推荐的做法是让数据类实现Parcelable(效率更高)或Serializable接口,这样可以直接通过Bundle传递,完全不需要转成字符串。

方式1:实现Parcelable(推荐)

Parcelable是Android特有的序列化方式,比Serializable快很多,适合在组件间传递数据。需要让你的两个数据类都实现Parcelable:

首先是嵌套的AuctionDetailInfo:

data class AuctionDetailInfo(
    val AuctionNumber: Int,
    val AuctionStatus: Int,
    val InitiatorType: Int
) : Parcelable {
    // 从Parcel读取数据的构造函数
    constructor(parcel: Parcel) : this(
        parcel.readInt(),
        parcel.readInt(),
        parcel.readInt()
    )

    // 写入数据到Parcel
    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeInt(AuctionNumber)
        parcel.writeInt(AuctionStatus)
        parcel.writeInt(InitiatorType)
    }

    override fun describeContents(): Int = 0

    // 静态CREATOR对象,用于反序列化
    companion object CREATOR : Parcelable.Creator<AuctionDetailInfo> {
        override fun createFromParcel(parcel: Parcel): AuctionDetailInfo {
            return AuctionDetailInfo(parcel)
        }

        override fun newArray(size: Int): Array<AuctionDetailInfo?> {
            return arrayOfNulls(size)
        }
    }
}

然后是外层的InstrumentResponse:

data class InstrumentResponse(
    val AGM: Boolean,
    val AllOrNone: Boolean,
    val Bonus: Boolean,
    val Dividend: Boolean,
    val EGM: Boolean,
    val AuctionDetailInfo: AuctionDetailInfo
) : Parcelable {
    constructor(parcel: Parcel) : this(
        // 布尔类型用Byte存储,1为true,0为false
        parcel.readByte() != 0.toByte(),
        parcel.readByte() != 0.toByte(),
        parcel.readByte() != 0.toByte(),
        parcel.readByte() != 0.toByte(),
        parcel.readByte() != 0.toByte(),
        // 读取嵌套的Parcelable对象
        parcel.readParcelable(AuctionDetailInfo::class.java.classLoader)!!
    )

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeByte(if (AGM) 1 else 0)
        parcel.writeByte(if (AllOrNone) 1 else 0)
        parcel.writeByte(if (Bonus) 1 else 0)
        parcel.writeByte(if (Dividend) 1 else 0)
        parcel.writeByte(if (EGM) 1 else 0)
        parcel.writeParcelable(AuctionDetailInfo, flags)
    }

    override fun describeContents(): Int = 0

    companion object CREATOR : Parcelable.Creator<InstrumentResponse> {
        override fun createFromParcel(parcel: Parcel): InstrumentResponse {
            return InstrumentResponse(parcel)
        }

        override fun newArray(size: Int): Array<InstrumentResponse?> {
            return arrayOfNulls(size)
        }
    }
}
传递与接收数据
  • 源Fragment传递:
// 假设你已经创建了InstrumentResponse实例
val response = InstrumentResponse(
    AGM = false,
    AllOrNone = true,
    Bonus = true,
    Dividend = true,
    EGM = false,
    AuctionDetailInfo = AuctionDetailInfo(0, 0, 0)
)

// 放入Bundle
val bundle = Bundle().apply {
    putParcelable("INSTRUMENT_RESPONSE_KEY", response)
}

// 传递给目标Fragment(比如用FragmentManager或Navigation组件)
val targetFragment = TargetFragment()
targetFragment.arguments = bundle
  • 目标Fragment接收:
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    val response = arguments?.getParcelable<InstrumentResponse>("INSTRUMENT_RESPONSE_KEY")
    // 拿到数据后就可以正常使用了
}

方式2:实现Serializable(简单但效率低)

如果觉得Parcelable写起来麻烦,也可以用Serializable,它是Java的标准序列化接口,代码更简洁,但效率不如Parcelable:

// 两个数据类都实现Serializable
data class AuctionDetailInfo(
    val AuctionNumber: Int,
    val AuctionStatus: Int,
    val InitiatorType: Int
) : Serializable

data class InstrumentResponse(
    val AGM: Boolean,
    val AllOrNone: Boolean,
    val Bonus: Boolean,
    val Dividend: Boolean,
    val EGM: Boolean,
    val AuctionDetailInfo: AuctionDetailInfo
) : Serializable
传递与接收
  • 传递:
bundle.putSerializable("INSTRUMENT_RESPONSE_KEY", response)
  • 接收:
val response = arguments?.getSerializable("INSTRUMENT_RESPONSE_KEY") as? InstrumentResponse

总结

  • 绝对不要用toString()的输出转回数据类,这种方式既脆弱又难维护;
  • 优先选择Parcelable实现组件间数据类传递,效率更高,符合Android最佳实践;
  • 追求代码简洁的话可以用Serializable,但要注意它的性能劣势。

内容的提问来源于stack exchange,提问作者Rupesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:58:49