欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android通過(guò)Intent傳遞自定義對(duì)象的兩種方式

 更新時(shí)間:2025年07月21日 08:30:33   作者:雨白  
我們經(jīng)常會(huì)使用Intent來(lái)啟動(dòng)Activity、發(fā)送廣播等,在進(jìn)行上述操作的過(guò)程中,我們還可以往Intent對(duì)象中添加額外的數(shù)據(jù),但問(wèn)題在于putExtra可傳遞的數(shù)據(jù)類型是有限的,如果你想傳遞自定義對(duì)象,就行不通了,所以接下來(lái)就來(lái)學(xué)習(xí)如何通過(guò)Intent傳遞自定義對(duì)象

前言

我們經(jīng)常會(huì)使用 Intent 來(lái)啟動(dòng) Activity、發(fā)送廣播等。在進(jìn)行上述操作的過(guò)程中,我們還可以往 Intent 對(duì)象中添加額外的數(shù)據(jù),比如:

// MainActivity.kt
val intent = Intent(this, AnotherActivity::class.java)
intent.putExtra("name", "Martin")
intent.putExtra("age", 21)
startActivity(intent)

以此來(lái)完成數(shù)據(jù)的傳遞:

// AnotherActivity.kt
val name = intent.getStringExtra("name") ?: "Unknown Name"
val age = intent.getIntExtra("age", -1)

但問(wèn)題在于 putExtra 可傳遞的數(shù)據(jù)類型是有限的,如果你想傳遞自定義對(duì)象,就行不通了。但請(qǐng)別擔(dān)心,我們接下來(lái)就來(lái)學(xué)習(xí)如何通過(guò) Intent 傳遞自定義對(duì)象。

方式一:Serializable

Serializable 翻譯過(guò)來(lái)是序列化的意思,表示將一個(gè)對(duì)象轉(zhuǎn)換為可存儲(chǔ)或可傳輸?shù)臓顟B(tài),序列化后的對(duì)象可被存儲(chǔ)到本地,也可在網(wǎng)絡(luò)上進(jìn)行傳輸。

序列化一個(gè)類,其實(shí)非常簡(jiǎn)單,只需讓這個(gè)類實(shí)現(xiàn) Serializable 接口即可。例如:

class Person : Serializable {
    var name = ""
    var age = 0
}

這樣,所有的 Person 對(duì)象都是可序列化的了?,F(xiàn)在,我們想要傳遞一個(gè) Person 對(duì)象,只需這樣:

val person = Person()
person.name = "Jack"
person.age = 21
val intent = Intent(this, AnotherActivity::class.java)
intent.putExtra("person", person)
startActivity(intent)

那么,該怎么從 Intent 中取出這個(gè) Person 對(duì)象呢?

答案是使用 getSerializableExtra() 方法獲取序列化對(duì)象,再向下轉(zhuǎn)型為 Person 對(duì)象即可。

// val person_from_intent: Person = intent.getSerializableExtra("person") as Person

不過(guò),這個(gè)方法已經(jīng)被廢棄了。原因在于它不能保證類型安全,如果獲取到的不是 Person 類型的對(duì)象,又或是鍵名拼寫(xiě)錯(cuò)誤導(dǎo)致返回 null,那么在運(yùn)行時(shí),as 強(qiáng)制類型轉(zhuǎn)換可能會(huì)失敗并導(dǎo)致程序崩潰。

所以,現(xiàn)在我們會(huì)使用更安全的重載方法 getSerializableExtra(String, Class<T>)。這個(gè)方法是在 Android 13 (API 33) 引入的,為了兼容所有版本,我們需要這樣寫(xiě):

val person: Person? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    intent.getSerializableExtra("person", Person::class.java)
} else {
    // 使用 as? 安全轉(zhuǎn)型來(lái)避免崩潰
    @Suppress("DEPRECATION")
    intent.getSerializableExtra("person") as? Person
}

這樣,我們就成功實(shí)現(xiàn)了通過(guò) Intent 來(lái)傳遞自定義對(duì)象。

最后注意一點(diǎn):在這個(gè)過(guò)程中,會(huì)將對(duì)象序列化為可存儲(chǔ)或可傳輸?shù)臓顟B(tài),再將其反序列化為一個(gè)新的對(duì)象。雖然這兩個(gè)對(duì)象存儲(chǔ)的數(shù)據(jù)一致,但其實(shí)是兩個(gè)不相同的對(duì)象。

方式二:Parcelable

我們也可以通過(guò) Parcelable 來(lái)完成。只不過(guò)它的實(shí)現(xiàn)原理是將完整的對(duì)象進(jìn)行分解,使得分解后的每一個(gè)部分都是 Intent 所支持的數(shù)據(jù)類型,這樣也能實(shí)現(xiàn)通過(guò) Intent 來(lái)傳遞自定義對(duì)象的功能。

如果使用 Parcelable 的實(shí)現(xiàn)方式,Person 類的代碼將會(huì)是這樣的:

class Person(var name: String?, var age: Int) : Parcelable {

    constructor(parcel: Parcel) : this(
        parcel.readString(),
        parcel.readInt()
    )

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        // 將當(dāng)前類中的字段寫(xiě)出
        parcel.writeString(name)
        parcel.writeInt(age)
    }

    override fun describeContents(): Int {
        return 0
    }
    
    // 注意:讀取字段的順序需要和寫(xiě)出字段的順序保持一致。
    companion object CREATOR : Parcelable.Creator<Person> {
        override fun createFromParcel(parcel: Parcel): Person {
            return Person(parcel)
        }

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

可以看到,手動(dòng)編寫(xiě)這些模版代碼非常繁瑣。為此,Kotlin 提供了一種更加簡(jiǎn)便的用法。

我們先在 app/build.gradle.kts 文件中添加插件依賴:

plugins { 
    id("kotlin-parcelize")
}

然后,修改 Person 類:

import kotlinx.parcelize.Parcelize

@Parcelize
data class Person(var name: String, var age: Int) : Parcelable

只需加上一個(gè) @Parcelize 注解,就可以省去了一大堆模板代碼的麻煩。

注意:使用 @Parcelize 時(shí),所有要傳遞的數(shù)據(jù)都必須在類的主構(gòu)造函數(shù)中聲明。

接下來(lái),在獲取 Intent 中的數(shù)據(jù)時(shí),只需使用 getParcelableExtra() 方法即可。同樣地,需要處理版本兼容問(wèn)題:

val person: Person? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    intent.getParcelableExtra("person", Person::class.java)
} else {
    @Suppress("DEPRECATION")
    intent.getParcelableExtra<Person>("person")
}

對(duì)比

對(duì)比 SerializableParcelable 這兩種方式,Serializable 的實(shí)現(xiàn)非常簡(jiǎn)單,但它序列化時(shí)會(huì)用到反射,導(dǎo)致性能開(kāi)銷大。Parcelable 則通過(guò)顯式的讀寫(xiě)操作來(lái)分解對(duì)象,沒(méi)有反射的開(kāi)銷,效率要高得多。

因此,在安卓開(kāi)發(fā)中,通常情況下,我們都會(huì)選擇使用 Parcelable 的方式。

以上就是Android通過(guò)Intent傳遞自定義對(duì)象的兩種方式的詳細(xì)內(nèi)容,更多關(guān)于Android Intent傳遞自定義對(duì)象的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論