Skip to content

Commit

Permalink
1、优化 debugMode 下打包速度
Browse files Browse the repository at this point in the history
  • Loading branch information
FlyJingFish committed Jun 7, 2024
1 parent 31efbb9 commit 0d7f68e
Show file tree
Hide file tree
Showing 12 changed files with 90 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package com.flyjingfish.android_aop_plugin.beans

class WovenResult(val byteArray: ByteArray,val modified: Boolean)
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ enum class RootBooleanConfig(
val defaultValue: Boolean,
) {
DEBUG_MODE("androidAop.debugMode", false),
REFLECT_INVOKE_METHOD("androidAop.reflectInvokeMethod", false),
ONLY_DEBUG("androidAop.debugMode.variantOnlyDebug", true),
INCREMENTAL("androidAop.debugMode.isIncremental", true);
INCREMENTAL("androidAop.debugMode.isIncremental", true),
REFLECT_INVOKE_METHOD("androidAop.reflectInvokeMethod", false),
REFLECT_INVOKE_METHOD_ONLY_DEBUG("androidAop.reflectInvokeMethod.variantOnlyDebug", false);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import org.gradle.api.Plugin
import org.gradle.api.Project

abstract class BasePlugin :Plugin<Project> {
var reflectInvokeMethod = false
private var reflectInvokeMethod = false
private var reflectInvokeMethodOnlyDebug = false
private var debugMode = false
private var onlyDebug = false
private var isIncremental = true
Expand All @@ -14,10 +15,12 @@ abstract class BasePlugin :Plugin<Project> {
val debugModeStr = project.properties[RootBooleanConfig.DEBUG_MODE.propertyName]?:"${RootBooleanConfig.DEBUG_MODE.defaultValue}"
val onlyModeStr = project.properties[RootBooleanConfig.ONLY_DEBUG.propertyName]?:"${RootBooleanConfig.ONLY_DEBUG.defaultValue}"
val isIncrementalStr = project.properties[RootBooleanConfig.INCREMENTAL.propertyName]?:"${RootBooleanConfig.INCREMENTAL.defaultValue}"
val reflectInvokeMethodDebugStr = project.properties[RootBooleanConfig.REFLECT_INVOKE_METHOD_ONLY_DEBUG.propertyName]?:"${RootBooleanConfig.REFLECT_INVOKE_METHOD_ONLY_DEBUG.defaultValue}"
debugMode = debugModeStr.toString() == "true"
reflectInvokeMethod = reflectInvokeMethodStr.toString() == "true"
onlyDebug = onlyModeStr.toString() == "true"
isIncremental = isIncrementalStr.toString() == "true"
reflectInvokeMethodOnlyDebug = reflectInvokeMethodDebugStr.toString() == "true"
}

fun isIncremental():Boolean{
Expand All @@ -43,4 +46,20 @@ abstract class BasePlugin :Plugin<Project> {
false
}
}

fun isReflectInvokeMethod(buildTypeName :String?,variantName :String):Boolean{
return if (reflectInvokeMethod){
if (reflectInvokeMethodOnlyDebug){
if (buildTypeName != null){
buildTypeName.lowercase() == "debug"
}else{
variantName.lowercase().contains("debug")
}
}else{
true
}
}else{
false
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ class CompilePlugin(private val root:Boolean): BasePlugin() {
}
}
if (localInput.isNotEmpty()){
ClassFileUtils.reflectInvokeMethod = reflectInvokeMethod
ClassFileUtils.reflectInvokeMethod = isReflectInvokeMethod(buildTypeName,variantName)
val output = File(javaCompile.destinationDirectory.asFile.orNull.toString())
val task = CompileAndroidAopTask(jarInput,localInput,output,project,isApp,
File(Utils.aopCompileTempDir(project,variantName)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ object TransformPlugin : BasePlugin() {
// println("TransformPlugin=variant=${variant.name}, variant.buildType=${variant.buildType},isDebug=${isDebugMode(buildTypeName,variant.name)}")
if (androidAopConfig.enabled && !isDebugMode(buildTypeName,variant.name)){
ClassFileUtils.debugMode = false
ClassFileUtils.reflectInvokeMethod = reflectInvokeMethod
ClassFileUtils.reflectInvokeMethod = isReflectInvokeMethod(buildTypeName,variant.name)
val task = project.tasks.register("${variant.name}AssembleAndroidAopTask", AssembleAndroidAopTask::class.java){
it.variant = variant.name
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import org.objectweb.asm.Opcodes
class MethodReplaceInvokeAdapter(private val className:String,
private val methodNameDesc:String, methodVisitor: MethodVisitor?) :
MethodVisitor(Opcodes.ASM9, methodVisitor) {

interface OnResultListener{
fun onBack()
}
var onResultListener : OnResultListener ?= null
override fun visitMethodInsn(
opcode: Int,
owner: String,
Expand Down Expand Up @@ -47,6 +52,7 @@ class MethodReplaceInvokeAdapter(private val className:String,
replaceMethodInfo.newMethodDesc,
false
)
onResultListener?.onBack()
} else {
super.visitMethodInsn(opcode, owner, name, descriptor, isInterface)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ open class MethodReplaceInvokeVisitor(
classVisitor: ClassVisitor
) : ReplaceBaseClassVisitor(classVisitor) {
lateinit var className: String
var replaced = false
override fun visit(
version: Int,
access: Int,
Expand All @@ -31,6 +32,11 @@ open class MethodReplaceInvokeVisitor(

if (mv != null && Utils.isHasMethodBody(access)) {
mv = MethodReplaceInvokeAdapter(className,"$name$descriptor",mv)
mv.onResultListener = object : MethodReplaceInvokeAdapter.OnResultListener{
override fun onBack() {
replaced = true
}
}
}
return mv
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ open class ReplaceBaseClassVisitor(
) : ClassVisitor(Opcodes.ASM9, classVisitor) {
lateinit var thisClassName:String
private var oldSuperName:String?=null
private var modifyExtendsClassName:String?=null
var modifyExtendsClassName:String?=null
var isHasStaticClock = false
var hasCollect = false
override fun visit(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ abstract class AssembleAndroidAopTask : DefaultTask() {
if (byteArray.isNotEmpty()){
try {
val newByteArray = AopTaskUtils.wovenIntoCodeForReplace(byteArray)
ByteArrayInputStream(newByteArray).use {
ByteArrayInputStream(newByteArray.byteArray).use {
jarOutput.saveEntry(jarEntryName,it)
}
// newClasses.add(newByteArray)
Expand All @@ -254,7 +254,7 @@ abstract class AssembleAndroidAopTask : DefaultTask() {
if (byteArray.isNotEmpty()){
try {
val newByteArray = AopTaskUtils.wovenIntoCodeForExtendsClass(byteArray)
ByteArrayInputStream(newByteArray).use {
ByteArrayInputStream(newByteArray.byteArray).use {
jarOutput.saveEntry(jarEntryName,it)
}
// newClasses.add(newByteArray)
Expand Down Expand Up @@ -387,7 +387,7 @@ abstract class AssembleAndroidAopTask : DefaultTask() {
if (byteArray.isNotEmpty()){
try {
val newByteArray = AopTaskUtils.wovenIntoCodeForReplace(byteArray)
ByteArrayInputStream(newByteArray).use {
ByteArrayInputStream(newByteArray.byteArray).use {
jarOutput.saveEntry(entryName,it)
}
// newClasses.add(newByteArray)
Expand All @@ -407,7 +407,7 @@ abstract class AssembleAndroidAopTask : DefaultTask() {
if (byteArray.isNotEmpty()){
try {
val newByteArray = AopTaskUtils.wovenIntoCodeForExtendsClass(byteArray)
ByteArrayInputStream(newByteArray).use {
ByteArrayInputStream(newByteArray.byteArray).use {
jarOutput.saveEntry(entryName,it)
}
// newClasses.add(newByteArray)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,19 +109,23 @@ class CompileAndroidAopTask(
}
val relativePath = directory.toURI().relativize(file.toURI()).path

val outFile = File(tmpCompileDir.absolutePath+"/"+relativePath)
if (!outFile.parentFile.exists()){
outFile.parentFile.mkdirs()
}
if (!outFile.exists()){
outFile.createNewFile()
}
val tmpFile = TmpFile(file,outFile)
tempFiles.add(tmpFile)

val methodsRecord: HashMap<String, MethodRecord>? = WovenInfoUtils.getClassMethodRecord(file.absolutePath)
val thisClassName = Utils.slashToDotClassName(entryName).replace(_CLASS,"")
val hasCollect = WovenInfoUtils.aopCollectClassMap[thisClassName] != null
val outFile = File(tmpCompileDir.absolutePath+"/"+relativePath)
fun mkOutFile(){
if (!outFile.parentFile.exists()){
outFile.parentFile.mkdirs()
}
if (!outFile.exists()){
outFile.createNewFile()
}
val tmpFile = TmpFile(file,outFile)
tempFiles.add(tmpFile)
}
if (methodsRecord != null){
mkOutFile()
FileInputStream(file).use { inputs ->
val byteArray = WovenIntoCode.modifyClass(inputs.readAllBytes(),methodsRecord,hasReplace)
ByteArrayInputStream(byteArray).use {
Expand All @@ -131,9 +135,9 @@ class CompileAndroidAopTask(
}
}else{
fun copy(){
file.inputStream().use {
outFile.saveEntry(it)
}
// file.inputStream().use {
// outFile.saveEntry(it)
// }
}
val isClassFile = file.name.endsWith(_CLASS)
val tranEntryName = file.absolutePath.replace("/", ".")
Expand All @@ -146,8 +150,11 @@ class CompileAndroidAopTask(
if (byteArray.isNotEmpty()){
try {
val newByteArray = AopTaskUtils.wovenIntoCodeForReplace(byteArray)
ByteArrayInputStream(newByteArray).use {
outFile.saveEntry(it)
if (newByteArray.modified){
mkOutFile()
ByteArrayInputStream(newByteArray.byteArray).use {
outFile.saveEntry(it)
}
}
} catch (e: Exception) {
copy()
Expand All @@ -165,8 +172,11 @@ class CompileAndroidAopTask(
if (byteArray.isNotEmpty()){
try {
val newByteArray = AopTaskUtils.wovenIntoCodeForExtendsClass(byteArray)
ByteArrayInputStream(newByteArray).use {
outFile.saveEntry(it)
if (newByteArray.modified){
mkOutFile()
ByteArrayInputStream(newByteArray.byteArray).use {
outFile.saveEntry(it)
}
}
} catch (e: Exception) {
copy()
Expand Down Expand Up @@ -211,6 +221,7 @@ class CompileAndroidAopTask(
WovenIntoCode.wovenStaticCode(cw, thisClassName)
}

mkOutFile()
val newByteArray = cw.toByteArray()
ByteArrayInputStream(newByteArray).use {
outFile.saveEntry(it)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.flyjingfish.android_aop_plugin.utils
import com.flyjingfish.android_aop_plugin.beans.ClassMethodRecord
import com.flyjingfish.android_aop_plugin.beans.MethodRecord
import com.flyjingfish.android_aop_plugin.beans.ReplaceMethodInfo
import com.flyjingfish.android_aop_plugin.beans.WovenResult
import com.flyjingfish.android_aop_plugin.config.AndroidAopConfig
import com.flyjingfish.android_aop_plugin.scanner_visitor.ClassSuperScanner
import com.flyjingfish.android_aop_plugin.scanner_visitor.MethodReplaceInvokeVisitor
Expand Down Expand Up @@ -256,12 +257,13 @@ object AopTaskUtils {

}

fun wovenIntoCodeForReplace(byteArray: ByteArray): ByteArray {
fun wovenIntoCodeForReplace(byteArray: ByteArray): WovenResult {
val cr = ClassReader(byteArray)
val cw = ClassWriter(ClassWriter.COMPUTE_FRAMES)
var thisHasCollect = false
var thisHasStaticClock = false
var thisCollectClassName :String ?= null
var replaceResult = false
val cv = object : MethodReplaceInvokeVisitor(cw){
override fun visit(
version: Int,
Expand Down Expand Up @@ -292,22 +294,29 @@ object AopTaskUtils {
thisHasStaticClock = isHasStaticClock
return mv
}

override fun visitEnd() {
super.visitEnd()
replaceResult = replaced
}
}
thisCollectClassName?.let {
if (thisHasCollect && !thisHasStaticClock){
WovenIntoCode.wovenStaticCode(cw, it)
replaceResult = true
}
}
cr.accept(cv, ClassReader.SKIP_DEBUG or ClassReader.SKIP_FRAMES)
return cw.toByteArray()
return WovenResult(cw.toByteArray(),replaceResult)
}

fun wovenIntoCodeForExtendsClass(byteArray:ByteArray):ByteArray{
fun wovenIntoCodeForExtendsClass(byteArray:ByteArray): WovenResult {
val cr = ClassReader(byteArray)
val cw = ClassWriter(ClassWriter.COMPUTE_FRAMES)
var thisHasCollect = false
var thisHasStaticClock = false
var thisCollectClassName :String ?= null
var replaceResult = false
val cv = object : ReplaceBaseClassVisitor(cw){
override fun visit(
version: Int,
Expand All @@ -320,6 +329,7 @@ object AopTaskUtils {
super.visit(version, access, name, signature, superName, interfaces)
thisHasCollect = hasCollect
thisCollectClassName = thisClassName
replaceResult = modifyExtendsClassName != null
}
override fun visitMethod(
access: Int,
Expand All @@ -342,10 +352,12 @@ object AopTaskUtils {
thisCollectClassName?.let {
if (thisHasCollect && !thisHasStaticClock){
WovenIntoCode.wovenStaticCode(cw, it)
replaceResult = true
}
}

cr.accept(cv, ClassReader.SKIP_DEBUG or ClassReader.SKIP_FRAMES)
return cw.toByteArray()

return WovenResult(cw.toByteArray(),replaceResult)
}
}
3 changes: 2 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@ TestVersion = 1.8.3
SonatypeTestCode = 1395
TestType = 0
androidAop.debugMode = true
androidAop.reflectInvokeMethod = false
androidAop.debugMode.variantOnlyDebug = true
androidAop.reflectInvokeMethod = false
androidAop.reflectInvokeMethod.variantOnlyDebug = false
# 0 mavenLocal 1 SonatypeCache 2 mavenCentral


Expand Down

0 comments on commit 0d7f68e

Please sign in to comment.