Kotlin序列化

  • Kotlin 下 Parcelable Serializable 使用

  • 资料来源:

    <>

  • 更新

    20.05.05
    

导语

  • 最近在重构 Nowakelock 的 ipc 部分,整理一下相关内容.
  • 首选肯定是 Parcelable ,无奈 hook 部分都在 frame 层,Parcelable 暂时无解.

序列化

  • 序列化和反序列化其实就是方便传输对象.
  • 这里是需要在几个系统 Service 里通过 Bundle 传递数据.
  • Parcelable 全部都在内存,效率高, 需要实现部分多,使用繁琐. (在 kotlin 不成立)
  • Serializable 实现简单,但是是基于反射实现的,故有性能损失,但是是最通用的.

Parcelable

  • 直接实现 Parcelable 确实略微繁琐.但是这是 kotlin 啊.

  • Android stuio 的 kotlin 插件,只需要在数据类添加 @Parcelize 即可.

  • 启用 androidExtensions,在应用的 build.gradle 中添加.

    androidExtensions {
    //  features = ["parcelize"] //仅使用 @Parcelize
        experimental = true
    }
    
  • 示例

    @Parcelize
    data class Test2(
        val name: String?,
        var packageName: String? = "",
        var count: Int = 0,
        var blockCount: Int = 0,
        var countTime: Long = 0,
        var blockCountTime: Long = 0
    ) : Parcelable
    
  • 使用生成插件我们可以看到手写情况下,我们需要写多少代码.

    data class Test2(
      val name: String?,
      var packageName: String? = "",
      var count: Int = 0,
      var blockCount: Int = 0,
      var countTime: Long = 0,
      var blockCountTime: Long = 0
    ) : Parcelable {
      constructor(source: Parcel) : this(
          source.readString(),
          source.readString(),
          source.readInt(),
          source.readInt(),
          source.readLong(),
          source.readLong()
      )
    
      override fun describeContents() = 0
    
      override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
          writeString(name)
          writeString(packageName)
          writeInt(count)
          writeInt(blockCount)
          writeLong(countTime)
          writeLong(blockCountTime)
      }
    
      companion object {
          @JvmField
          val CREATOR: Parcelable.Creator<Test2> = object : Parcelable.Creator<Test2> {
              override fun createFromParcel(source: Parcel): Test2 = Test2(source)
              override fun newArray(size: Int): Array<Test2?> = arrayOfNulls(size)
          }
      }
    }
    

Serializable

  • 其他不多表了,直接是示例.

    data class Test(
      val name: String?,
      var packageName: String? = "",
      var count: Int = 0,
      var blockCount: Int = 0,
      var countTime: Long = 0,
      var blockCountTime: Long = 0
    ) : Serializable
    
  • 实现确实简单..

使用

  • 这里是配合 ContentProvider 的 call 方法,就不贴全部代码了.

  • 放入 Bundle

    val extras = Bundle()
    extras.putSerializable("Test",Test("test1","package1",2,2,2,2))
    extras.putParcelable("Test2", Test2("test1","package1",2,2,2,2))
    val bundle = context.contentResolver.call(url, method, null, extras)
    
  • 获取也类似..不再表述了.

Parcelable 坑

  • 相同的代码在 Android Test 中可以通过但是在 Hook 中就是不行.

  • 一直提示 android.os.BadParcelableException: ClassNotFoundException when unmarshalling:

  • 搜集过资料表示懵逼..class loader 不知道该怎么序列化.

  • 一种解释是: class loader 分为两类,一类是 framework classloader 可以加载 Android 的 class,另一个是 apk classloader 继承自 framework classloader ,既可以加载 android 的 class,也能加载应用的 class.但是 hook 的全是系统服务…

  • 另一种是注入的系统 Service 中没有定义好的 Parcelable 类.xposed 应该可以注入成员变量,待续…

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章