一行注解帮你搞定Parcelable

前言

android在序列化的时候有两种模式,一种是传统的Serializable,另外一种就是android特有的Parcelable方式。另种序列化有各自的选择方式 实现Parcelable的做用 1)永久性保存对象,保存对象的字节序列到本地文件中; 2)经过序列化对象在网络中传递对象; 3)经过序列化在进程间传递对象。 选择序列化方法的原则 1)在使用内存的时候,Parcelable比Serializable性能高,因此推荐使用Parcelable。 2)Serializable在序列化的时候会产生大量的临时变量,从而引发频繁的GC。 3)Parcelable不能使用在要将数据存储在磁盘上的状况,由于Parcelable不能很好的保证数据的持续性在外界有变化的状况下。尽管Serializable效率低点,但此时仍是建议使用Serializable 。android

能够看到当咱们不须要存储到磁盘时使用Parcelable这种序列化方式更加高效,可是有个问题,就是实现Parcelable须要编写大量的代码,尽管如今有一些ide插件能够帮你生成相应代码,可是一个bean类多出这么多代码也是蛮蛋疼的,并且看起来也较乱,因此我写了这个aop工具在编译成class文件时动态实现Parcelablegit

使用

在项目gradle文件里添加依赖github

buildscript {
    repositories {
       ....
        maven{
            url "https://dl.bintray.com/wuhaoxuan1225/maven/"
        }
        
    }
    dependencies {
        ....
        classpath 'com.skateboard.parcelablehelper:parcelablehelper:1.0.0'
        ....
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}
复制代码

在module的gradle文件里添加插件的引用bash

apply plugin: 'parcelablehelper'
复制代码

在须要实现Parcelable接口的类上添加注解列化网络

import com.skateboard.parcelableannoation.Parcelable;
import com.skateboard.parcelableannoation.Ignore;
@Parcelable
public class Demo {

    private String name;
    


}

复制代码

原理

结合android gradle的Transform以及asm来实现该功能,编写gradle插件,利用android gradle的Transform获取编译后生成的class文件,而后利用asm动态修改相应的添加注释的文件。app

核心代码

由于主要就是对Transfom的编译和ASM的编写,这里就不展开描述了,能够去看一看相关的文档,这里只是介绍一些基本的类的用途。maven

1递归生成class文件目录,并对标注了@Parcelable注解的类进行修改,生成相应代码

/**
 * 获取目录下class文件并调用asm解析
 * */
object ParcelableByteCodeUtil {


    fun transformDirectoryInput(input: File, output: File) {

        if (output.exists()) {
            FileUtil.forceDelete(output)
        }
        FileUtil.forceMkdir(output)
        val srcDirPath = input.absolutePath
        val destDirPath = output.absolutePath
        if (input.isDirectory) {
            input.listFiles().forEach {
                val destFilePath = it.absolutePath.replace(srcDirPath, destDirPath)
                val destFile = File(destFilePath)
                if (it.isDirectory) {
                    transformDirectoryInput(it, destFile)
                } else if (it.isFile) {
                    FileUtils.touch(destFile)
                    performClassParse(it, destFile)
                }
            }
        }

    }

    private fun performClassParse(inputFile: File, outputFile: File) {
        if (inputFile.name.endsWith(".class") && inputFile.name != "R.class" && inputFile.name != "BuildConfig.class" && !inputFile.name.startsWith("R$")) {
            ParcelableParser.parseClass(inputFile, outputFile)
        } else {
            FileUtil.writeToFile(inputFile, outputFile)
        }
    }

}
复制代码

2.ParcelableCreatorGenerator

这个类利用ASM动态生成CREATOR的内部类,用来对应实现Parcelable接口须要的CREATOR变量ide

3.ParcelableGenerateVisitor

生成Parcelable相应的接口方法,为相应的属性字段生产相应的write和read调用。工具

源码

Github性能

相关文章
相关标签/搜索