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

Android中如何在Activity间传递ZipEntry类型的ArrayList?

解决Activity间传递ZipEntry列表的问题

问题原因

java.util.zip.ZipEntry 虽实现了 Serializable 接口,但它的内部实现和所属的 ZipFile 强绑定,通过 Intent 传递时,系统的 Parcel 序列化机制无法正确处理它的某些内部属性,因此抛出类型未知的异常。

可行解决方案

1. 封装ZipEntry核心信息为自定义Parcelable类

提取ZipEntry中你需要的关键属性(如文件名、大小、是否为目录等),封装成实现Parcelable的自定义类,传递这个类的列表:

// 自定义Parcelable类,存储ZipEntry核心信息
data class ZipEntryInfo(
    val name: String,
    val size: Long,
    val compressedSize: Long,
    val isDirectory: Boolean
) : Parcelable {
    constructor(parcel: Parcel) : this(
        parcel.readString() ?: "",
        parcel.readLong(),
        parcel.readLong(),
        parcel.readByte() != 0.toByte()
    )

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeString(name)
        parcel.writeLong(size)
        parcel.writeLong(compressedSize)
        parcel.writeByte(if (isDirectory) 1 else 0)
    }

    override fun describeContents(): Int {
        return 0
    }

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

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

传递时转换列表:

// 将原ZipEntry列表转为自定义类列表
val entryInfoList = languageListAdapter.selectedItems.map { entry ->
    ZipEntryInfo(
        entry.name,
        entry.size,
        entry.compressedSize,
        entry.isDirectory
    )
}

// 传递到目标Activity
val newActIntent = Intent(this, InstallActivity::class.java)
newActIntent.putParcelableArrayListExtra("zip_entries", ArrayList(entryInfoList))
startActivity(newActIntent)

目标Activity接收:

val entryInfoList = intent.getParcelableArrayListExtra<ZipEntryInfo>("zip_entries")
// 如需原ZipEntry,可结合ZipFile重新获取

2. 传递Zip文件路径与选中文件名列表

如果所有ZipEntry来自同一个ZipFile,直接传递Zip文件路径和选中的ZipEntry名称列表,在目标Activity中重新打开ZipFile获取对应Entry:

传递时:

// 假设你已有Zip文件的本地路径
val zipFilePath = "/path/to/your/target.zip"
val selectedEntryNames = languageListAdapter.selectedItems.map { it.name }

val newActIntent = Intent(this, InstallActivity::class.java)
newActIntent.putExtra("zip_file_path", zipFilePath)
newActIntent.putStringArrayListExtra("selected_entry_names", ArrayList(selectedEntryNames))
startActivity(newActIntent)

目标Activity接收并获取ZipEntry:

val zipFilePath = intent.getStringExtra("zip_file_path") ?: return
val selectedEntryNames = intent.getStringArrayListExtra("selected_entry_names") ?: return

ZipFile(zipFilePath).use { zipFile ->
    val selectedEntries = selectedEntryNames.mapNotNull { name ->
        zipFile.getEntry(name)
    }
    // 使用获取到的selectedEntries
}

3. 全局单例暂存列表

如果两个Activity在同一进程内,可用单例类暂存列表,跳过序列化传递:

// 单例暂存类
object TempDataHolder {
    var selectedZipEntries: List<ZipEntry>? = null
}

传递前暂存:

TempDataHolder.selectedZipEntries = languageListAdapter.selectedItems
val newActIntent = Intent(this, InstallActivity::class.java)
startActivity(newActIntent)

目标Activity获取:

val selectedEntries = TempDataHolder.selectedZipEntries
// 使用完成后清空数据,避免内存泄漏
TempDataHolder.selectedZipEntries = null

注意:此方法仅适用于同一进程内的Activity跳转,且务必在使用后清空暂存数据,防止内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 14:20:27