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
/**
* 獲取目錄下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)
}
}
}
複製代碼
這個類利用ASM動態生成CREATOR的內部類,用來對應實現Parcelable接口須要的CREATOR變量ide
生成Parcelable相應的接口方法,爲相應的屬性字段生產相應的write和read調用。工具
Github性能