рдЬреНрд╡рд╛рдЗрди рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп
рдпрд╣ рд╕рдм рдЗрд╕ рддрдереНрдп рд╕реЗ рд╢реБрд░реВ рд╣реБрдЖ рдерд╛ рдХрд┐ рдореИрдВ рдПрдВрдбреНрд░реЙрдЗрдб рд╡рд┐рдХрд╛рд╕ (рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ) рдореЗрдВ рдЗрд╕рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдЧреНрд░реИрдбрд▓ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреА рд╕реВрдХреНрд╖реНрдорддрд╛рдУрдВ рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ред рдореИрдВрдиреЗ рдЬреАрд╡рди рдЪрдХреНрд░ рдФрд░ рдкреБрд╕реНрддрдХреЛрдВ рдХреЗ рд╕рд╛рде рд╢реБрд░реБрдЖрдд рдХреА, рдзреАрд░реЗ-рдзреАрд░реЗ рд╕рд░рд▓ рдХрд╛рд░реНрдп рд▓рд┐рдЦреЗ, рдЕрдкрдирд╛ рдкрд╣рд▓рд╛ рдЧреНрд░реИрдбрд▓ рдкреНрд▓рдЧрдЗрди рдмрдирд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА ( рдмрд┐рд▓реНрдбрд╕реНрдХреИрди рдореЗрдВ ) рдФрд░ рдлрд┐рд░ рдпрд╣ рд╢реБрд░реВ рд╣реБрдЖред
рдПрдВрдбреНрд░реЙрдЗрдб рд╡рд┐рдХрд╛рд╕ рдХреА рд╡рд╛рд╕реНрддрд╡рд┐рдХ рджреБрдирд┐рдпрд╛ рдХреЗ рдХрд░реАрдм рдХреБрдЫ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓реЗрддреЗ рд╣реБрдП, рдЙрдиреНрд╣реЛрдВрдиреЗ рдПрдХ рдкреНрд▓рдЧрдЗрди рд▓рд┐рдЦрд╛, рдЬреЛ xml рдорд╛рд░реНрдХрдЕрдк рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рд▓реЗрдЖрдЙрдЯ рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╡рд┐рдЪрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдВрдХ рдХреЗ рд╕рд╛рде рдЙрди рдкрд░ рдПрдХ рдЬрд╛рд╡рд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рддрд╛ рд╣реИред рддрдм рдЙрдиреНрд╣реЛрдВрдиреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдирд┐рдлрд╝реЗрд╕реНрдЯ (рдпрд╣ рдХрд╛рд░реНрдп рдбреНрд░рд╛рдлреНрдЯ рдкрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдерд╛) рдХреЗ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдмрд╛рдж рд▓рд┐рдпрд╛, рдХреНрдпреЛрдВрдХрд┐ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдмрд╛рдж рдкреНрд░рдХрдЯрди рдореЗрдВ рд▓рдЧрднрдЧ 5k рд▓рд╛рдЗрдиреЗрдВ рд▓рдЧреАрдВ, рдФрд░ рдЗрд╕ рддрд░рд╣ рдХреА xml рдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рде IDE рдореЗрдВ рдХрд╛рдо рдХрд░рдирд╛ рдХрд╛рдлреА рдореБрд╢реНрдХрд┐рд▓ рд╣реИред
рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдПрдВрдбреНрд░реЙрдЗрдб рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдФрд░ рд╕рдВрд╕рд╛рдзрди рдХреИрд╕реЗ рдЙрддреНрдкрдиреНрди рд╣реЛрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╕рдордп рдХреЗ рд╕рд╛рде рдореБрдЭреЗ рдХреБрдЫ рдФрд░ рдЪрд╛рд╣рд┐рдП рдерд╛ред рдПрдХ рд╡рд┐рдЪрд╛рд░ рдерд╛ рдХрд┐ рдПрдПрд╕рдЯреА (рдПрдмреНрд╕рдЯреНрд░реИрдХреНрдЯ рд╕рд┐рдВрдЯреЗрдХреНрд╕ рдЯреНрд░реА) рдХреЛ рд╕рдВрдХрд▓рди рдХреЗ рд╕рдордп рдореЗрдВ рдардВрдбрд╛ рдХрд░рдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдЧреНрд░реВрд╡реА рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рддрд╛ рд╣реИ ред рдЗрд╕ рддрд░рд╣ рдХреЗ рд░реВрдкрд╛рдВрддрд░реЛрдВ рд╕реЗ рдХрдИ рд╕рдВрднрд╛рд╡рдирд╛рдПрдБ рдЦреБрд▓рддреА рд╣реИрдВ, рдПрдХ рдХрд▓реНрдкрдирд╛ рд╣реЛрдЧреАред
рдЗрд╕рд▓рд┐рдП рдХрд┐ рд╕рд┐рджреНрдзрд╛рдВрдд рд╕рд┐рд░реНрдл рдПрдХ рд╕рд┐рджреНрдзрд╛рдВрдд рдирд╣реАрдВ рдерд╛, рдореИрдВрдиреЗ рдПрдВрдбреНрд░реЙрдЗрдб рд╡рд┐рдХрд╛рд╕ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рдХреБрдЫ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд╕рд╛рде рд╡рд┐рд╖рдп рдХреЗ рдЕрдзреНрдпрдпрди рдХреЛ рд╕реБрджреГрдврд╝ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ред рдкрд╣рд▓реА рдмрд╛рдд рдЬреЛ рджрд┐рдорд╛рдЧ рдореЗрдВ рдЖрдИ рд╡рд╣ рдереА, рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдкреБрд░реНрдЬрд╝реЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдирд╛ред рдореЛрдЯреЗ рддреМрд░ рдкрд░, рдмрдВрдбрд▓ рдореЗрдВ рдмрдЪрдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЪрд░ рдиреНрдпреВрдирддрдо рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ рдХреЗ рд╕рд╛рде рдпрдерд╛рд╕рдВрднрд╡ рд╕рд░рд▓ рд╣реИрдВред
рдХрд╣рд╛рдБ рд╕реЗ рд╢реБрд░реВ рдХрд░реЗрдВ?
- рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЖрдкрдХреЛ рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдПрдВрдбреНрд░реЙрдЗрдб рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдЧреНрд░реИрдбрд▓ рдЬреАрд╡рди рдЪрдХреНрд░ рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдлрд╛рдЗрд▓реЛрдВ рддрдХ рдХреИрд╕реЗ рдкрд╣реБрдВрдЪрд╛ рдЬрд╛рдП, рдЬрд┐рд╕реЗ рд╣рдо рдмрд╛рдж рдореЗрдВ рдмрджрд▓ рджреЗрдВрдЧреЗред
- рджреВрд╕рд░реЗ, рдЬрдм рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдлрд╛рдЗрд▓реЗрдВ рдорд┐рд▓рддреА рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдХреИрд╕реЗ рдареАрдХ рд╕реЗ рдмрджрд▓рдирд╛ рд╣реИред
рдЪрд▓рд┐рдП рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ:
рд╕рдВрдХрд▓рди рд╕рдордп рдкрд░ рдлрд╝рд╛рдЗрд▓реЛрдВ рддрдХ рдкрд╣реБрдБрдЪреЗрдВ
рдЪреВрдВрдХрд┐ рд╣рдо рд╕рдВрдХрд▓рди рд╕рдордп рдкрд░ рдлрд╛рдЗрд▓реЗрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдПрдХ рдЧреНрд░реИрдбрд▓ рдкреНрд▓рдЧрдЗрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдлрд╛рдЗрд▓реЛрдВ рдХреЛ рд░реЛрдХ рджреЗрдЧрд╛ рдФрд░ рдкрд░рд┐рд╡рд░реНрддрди рд╕реЗ рдирд┐рдкрдЯреЗрдЧрд╛ред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдкреНрд▓рдЧрдЗрди рдЬрд┐рддрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рдЙрддрдирд╛ рд╕рд░рд▓ рд╣реИред рд▓реЗрдХрд┐рди рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВ рдЖрдкрдХреЛ рджрд┐рдЦрд╛рддрд╛ рд╣реВрдБ рдХрд┐ рдкреНрд▓рдЧрдЗрди рдХреЗ рд╕рд╛рде build.gradle
рдореЙрдбреНрдпреВрд▓ рдлрд╝рд╛рдЗрд▓ build.gradle
рджрд┐рдЦрддреА рд╣реИ:
apply plugin: 'java-gradle-plugin' apply plugin: 'groovy' dependencies { implementation gradleApi() implementation 'com.android.tools.build:gradle:3.5.0' implementation 'com.android.tools.build:gradle-api:3.5.0' implementation 'org.ow2.asm:asm:7.1' }
apply plugin: 'java-gradle-plugin'
рдХрд╣рдирд╛ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдореЙрдбреНрдпреВрд▓ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдПрдХ рдврд╛рд▓ рдкреНрд▓рдЧрдЗрди рд╣реИредapply plugin: 'groovy'
рдЗрд╕ рдкреНрд▓рдЧрдЗрди рдХреЛ рдЦрд╛рдВрдЪреЗ рдкрд░ рд▓рд┐рдЦрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИ (рдпрд╣ рдпрд╣рд╛рдВ рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛, рдЖрдк рдХрдо рд╕реЗ рдХрдо Groovy, рдХрдо рд╕реЗ рдХрдо рдЬрд╛рд╡рд╛, рдХрдо рд╕реЗ рдХрдо Kotlin, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЪрд╛рд╣реЗрдВ) рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВред рдореИрдВ рдореВрд▓ рд░реВрдк рд╕реЗ рдЦрд╛рдВрдЪреЗ рдкрд░ рдкреНрд▓рдЧрдЗрдиреНрд╕ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдореЗрдВ рдЧрддрд┐рд╢реАрд▓ рдЯрд╛рдЗрдкрд┐рдВрдЧ рд╣реИ рдФрд░ рдХрднреА-рдХрднреА рдпрд╣ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдпрджрд┐ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рддреЛ рдЖрдк рдмрд╕ @TypeChecked
рдПрдиреЛрдЯреЗрд╢рди рдбрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВредimplementation gradleApi()
- implementation gradleApi()
рдПрдкреАрдЖрдИ рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ рддрд╛рдХрд┐ org.gradle.api.Plugin
, org.gradle.api.Project
, рдЖрджрд┐ рддрдХ рдкрд╣реБрдВрдЪ рд╣реЛред- рдПрдВрдбреНрд░реЙрдЗрдб рдкреНрд▓рдЧрдЗрди рдХреА рд╕рдВрд╕реНрдерд╛рдУрдВ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП
'com.android.tools.build:gradle:3.5.0'
рдФрд░ 'com.android.tools.build:gradle-api:3.5.0'
рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред 'com.android.tools.build:gradle-api:3.5.0'
рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП 'com.android.tools.build:gradle-api:3.5.0'
рд▓рд╛рдЗрдмреНрд░реЗрд░реА, рд╣рдо рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдж рдореЗрдВ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗред
рдЪрд▓реЛ рдкреНрд▓рдЧрдЗрди рдкрд░ рд╣реА рдЪрд▓рддреЗ рд╣реИрдВ, рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВрдиреЗ рдХрд╣рд╛, рдпрд╣ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ:
class YourPlugin implements Plugin<Project> { @Override void apply(@NonNull Project project) { boolean isAndroidApp = project.plugins.findPlugin('com.android.application') != null boolean isAndroidLib = project.plugins.findPlugin('com.android.library') != null if (!isAndroidApp && !isAndroidLib) { throw new GradleException( "'com.android.application' or 'com.android.library' plugin required." ) } BaseExtension androidExtension = project.extensions.findByType(BaseExtension.class) androidExtension.registerTransform(new YourTransform()) } }
рдЖрдЗрдП isAndroidApp
рдФрд░ isAndroidLib
рд╕рд╛рде рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рдпрд╣рд╛рдВ рд╣рдо рд╕рд┐рд░реНрдл рдпрд╣ isAndroidLib
рдХрд┐ рдпрд╣ рдПрдХ рдПрдВрдбреНрд░реЙрдЗрдб рдкреНрд░реЛрдЬреЗрдХреНрдЯ / рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╣реИ, рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рдПрдХ рдЕрдкрд╡рд╛рдж рдлреЗрдВрдХ рджреЗрдВред рдЕрдЧрд▓рд╛, YourTransform
рдорд╛рдзреНрдпрдо рд╕реЗ Android рдкреНрд▓рдЧрдЗрди рдореЗрдВ YourTransform
рд░рдЬрд┐рд╕реНрдЯрд░ рдХрд░реЗрдВред YourTransform
рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рдЖрд╡рд╢реНрдпрдХ рд╕реЗрдЯ рдФрд░ рдЙрдирдХреЗ рд╕рдВрднрд╛рд╡рд┐рдд рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЗрдХрд╛рдИ рд╣реИ; рдпрд╣ рдЕрдореВрд░реНрдд рд╡рд░реНрдЧ com.android.build.api.transform.Transform
рдХреЛ рдЗрдирд╣реЗрд░рд┐рдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
рдЖрдЗрдП рд╕реАрдзреЗ YourTransform
рдкрд░ YourTransform
, рдкрд╣рд▓реЗ рдЙрди рдореБрдЦреНрдп рддрд░реАрдХреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
class YourTransform extends Transform { @Override String getName() { return YourTransform.simpleName } @Override Set<QualifiedContent.ContentType> getInputTypes() { return TransformManager.CONTENT_CLASS } @Override Set<? super QualifiedContent.Scope> getScopes() { return TransformManager.PROJECT_ONLY } @Override boolean isIncremental() { return false } }
getName
- рдпрд╣рд╛рдВ рдЖрдкрдХреЛ рдЙрд╕ рдирд╛рдо рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдкрд░рд┐рд╡рд░реНрддрди рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдбрд┐рдмрдЧ рдЕрд╕реЗрдВрдмрд▓реА рдХреЗ рд▓рд┐рдП, рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдХрд╛рд░реНрдп рдХреЛ рдЗрд╕ рддрд░рд╣ рдХрд╣рд╛ рдЬрд╛рдПрдЧрд╛: transformClassesWithYourTransformForDebug
редgetInputTypes
- рдЗрдВрдЧрд┐рдд рдХрд░реЗрдВ рдХрд┐ рд╣рдо рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ: рдХрдХреНрд╖рд╛рдПрдВ, рд╕рдВрд╕рд╛рдзрди, рдпрд╛ рджреЛрдиреЛрдВ ( com.android.build.api.transform.QualifiedContent.DefaultContentType
рджреЗрдЦреЗрдВ)ред рдпрджрд┐ рдЖрдк CLASSES рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ рддреЛ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рдХреЗрд╡рд▓ рд╡рд░реНрдЧ рдлрд╛рдЗрд▓реЗрдВ рдорд┐рд▓реЗрдВрдЧреА, рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рд╡реЗ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВредgetScopes
- рдЗрдВрдЧрд┐рдд рдХрд░реЗрдВ рдХрд┐ рд╣рдо рдХреМрди рд╕реЗ рд╕реНрдХреЛрдк рдХреЛ рдмрджрд▓ рджреЗрдВрдЧреЗ (рджреЗрдЦреЗрдВ com.android.build.api.transform.QualifiedContent.Scope
)ред рд╕реНрдХреЛрдк рдлрд╛рдЗрд▓реЛрдВ рдХрд╛ рджрд╛рдпрд░рд╛ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ PROJECT_ONLY рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд╣рдо рдХреЗрд╡рд▓ рдЙрди рдлрд╛рдЗрд▓реЛрдВ рдХреЛ рдмрджрд▓ рджреЗрдВрдЧреЗ рдЬреЛ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЙрдбреНрдпреВрд▓ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИрдВред рдпрд╣рд╛рдВ рдЖрдк рдЙрдк-рдореЙрдбреНрдпреВрд▓, рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдЖрджрд┐ рднреА рд╢рд╛рдорд┐рд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВредisIncremental
- рдпрд╣рд╛рдВ рд╣рдо рдПрдВрдбреНрд░реЙрдЗрдб рдкреНрд▓рдЧ-рдЗрди рдХреЛ рдмрддрд╛рддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рд╣рдорд╛рд░рд╛ рдкрд░рд┐рд╡рд░реНрддрди рд╡реГрджреНрдзрд┐рд╢реАрд▓ рдЕрд╕реЗрдВрдмрд▓реА рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ: рдпрджрд┐ рд╕рд╣реА рд╣реИ, рддреЛ рд╣рдореЗрдВ рд╕рднреА рдкрд░рд┐рд╡рд░реНрддрд┐рдд, рдЬреЛрдбрд╝реА рдЧрдИ рдФрд░ рд╣рдЯрд╛рдИ рдЧрдИ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд╣рд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдпрджрд┐ рдЧрд▓рдд рд╣реИ, рддреЛ рд╕рднреА рдлрд╛рдЗрд▓реЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рд▓рд┐рдП рдЙрдбрд╝ рдЬрд╛рдПрдВрдЧреА, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЕрдЧрд░ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдХреЛрдИ рдмрджрд▓рд╛рд╡ рдирд╣реАрдВ рд╣реБрдП рдереЗред , рддреЛ рдкрд░рд┐рд╡рд░реНрддрди рдирд╣реАрдВ рдХрд╣рд╛ рдЬрд╛рдПрдЧрд╛ред
рд╕рдмрд╕реЗ рдмреБрдирд┐рдпрд╛рджреА рдФрд░ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд░рд╣рд╛ рдореАрдард╛ рд╡рд╣ рд╡рд┐рдзрд┐ рдЬрд┐рд╕рдореЗрдВ рдЯреНрд░рд╛рдВрд╕рдлрд╝реЙрд░реНрдо рдлрд╛рдЗрд▓реНрд╕ transform(TransformInvocation transformInvocation)
рд╣реЛрдЧрд╛ред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдореБрдЭреЗ рдЗрд╕ рд╡рд┐рдзрд┐ рдХреЗ рд╕рд╛рде рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╡рд┐рд╡рд░рдг рдирд╣реАрдВ рдорд┐рд▓рд╛, рдореБрдЭреЗ рдХреЗрд╡рд▓ рдЪреАрдиреА рд▓реЗрдЦ рдФрд░ рд╡рд┐рд╢реЗрд╖ рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдХреЗ рдмрд┐рдирд╛ рдХреБрдЫ рдЙрджрд╛рд╣рд░рдг рдорд┐рд▓реЗ, рдпрд╣рд╛рдВ рдПрдХ рд╡рд┐рдХрд▓реНрдк рд╣реИред
рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд░рддреЗ рд╕рдордп рдореИрдВрдиреЗ рдЬреЛ рд╕рдордЭрд╛ рдерд╛:
- рд╕рднреА рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ рдЪреЗрди рдЕрд╕реЗрдВрдмрд▓реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдЭреБрдХреЗ рд╣реБрдП рд╣реИрдВред рдпрд╣реА рд╣реИ, рдЖрдк рддрд░реНрдХ рд▓рд┐рдЦреЗрдВрдЧреЗ рдЬреЛ рд╣реЛрдЧрд╛
рдирд┐рдЪреЛрдбрд╝рд╛ рд╣реБрдЖ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕реНрдерд╛рдкрд┐рдд рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВред рдЖрдкрдХреЗ рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ рдХреЗ рдмрд╛рдж, рдПрдХ рдФрд░ рдХрд╛рдо рдХрд░реЗрдЧрд╛, рдЖрджрд┐ред - рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг: рднрд▓реЗ рд╣реА рдЖрдк рдХрд┐рд╕реА рднреА рдлрд╝рд╛рдЗрд▓ рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдирд╣реАрдВ рдмрдирд╛рддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдЙрди рдЬрд╛рд░ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдмрджрд▓рдирд╛ рдирд╣реАрдВ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЬреЛ рдЖрдкрдХреЗ рдкрд╛рд╕ рдЖрдПрдВрдЧреА, рдлрд┐рд░ рднреА рдЙрдиреНрд╣реЗрдВ рдмрджрд▓рдиреЗ рдХреЗ рдмрд┐рдирд╛ рдЖрдкрдХреА рдЖрдЙрдЯрдкреБрдЯ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рдХреЙрдкреА рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╣ рдЖрдЗрдЯрдо рдкрд╣рд▓реЗ рд╕реЗ рдЕрдиреБрд╕рд░рдг рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рдлрд╝рд╛рдЗрд▓ рдХреЛ рдЪреЗрди рдХреЗ рд╕рд╛рде рдХрд┐рд╕реА рдЕрдиреНрдп рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ рдореЗрдВ рдЖрдЧреЗ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЕрдВрдд рдореЗрдВ рдлрд╝рд╛рдЗрд▓ рдмрд╕ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реЛрдЧреАред
рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдХрд┐ рдЯреНрд░рд╛рдВрд╕рдлрд╝реЙрд░реНрдо рд╡рд┐рдзрд┐ рдХреНрдпрд╛ рджрд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП:
@Override void transform( TransformInvocation transformInvocation ) throws TransformException, InterruptedException, IOException { super.transform(transformInvocation) transformInvocation.outputProvider.deleteAll() transformInvocation.inputs.each { transformInput -> transformInput.directoryInputs.each { directoryInput -> File inputFile = directoryInput.getFile() File destFolder = transformInvocation.outputProvider.getContentLocation( directoryInput.getName(), directoryInput.getContentTypes(), directoryInput.getScopes(), Format.DIRECTORY ) transformDir(inputFile, destFolder) } transformInput.jarInputs.each { jarInput -> File inputFile = jarInput.getFile() File destFolder = transformInvocation.outputProvider.getContentLocation( jarInput.getName(), jarInput.getContentTypes(), jarInput.getScopes(), Format.JAR ) FileUtils.copyFile(inputFile, destFolder) } } }
рд╣рдорд╛рд░реЗ рдкреНрд░рд╡реЗрд╢ рджреНрд╡рд╛рд░ рдкрд░ TransformInvocation
рдЖрддрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдЖрдЧреЗ рдХреЗ рдкрд░рд┐рд╡рд░реНрддрдиреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдЬрд╛рдирдХрд╛рд░реА рд╣реЛрддреА рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдЙрд╕ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреЛ рд╕рд╛рдл рдХрд░рддреЗ рд╣реИрдВ, рдЬрд╣рд╛рдВ рдирдП transformInvocation.outputProvider.deleteAll()
рдлрд╛рдЗрд▓реЗрдВ рд░рд┐рдХреЙрд░реНрдб рдХреА рдЬрд╛рдПрдВрдЧреА, рдпрд╣ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ рд╡реГрджреНрдзрд┐рд╢реАрд▓ рдЕрд╕реЗрдВрдмрд▓реА рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЖрдкрдХреЛ рдЯреНрд░рд╛рдВрд╕рдлреЙрд░реНрдореЗрд╢рди рд╕реЗ рдкрд╣рд▓реЗ рдкреБрд░рд╛рдиреА рдлрд╛рдЗрд▓реЛрдВ рдХреЛ рд╣рдЯрд╛рдирд╛ рд╣реЛрдЧрд╛ред
рдЕрдЧрд▓рд╛, рд╣рдо рд╕рднреА рдЗрдирдкреБрдЯреЛрдВ рдкрд░ рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдЗрдирдкреБрдЯ рдореЗрдВ рд╣рдо рдбрд╛рдпрд░реЗрдХреНрдЯреНрд░реА рдФрд░ рдЬрд╛рд░ рдлрд╛рдЗрд▓реЛрдВ рдкрд░ рдЬрд╛рддреЗ рд╣реИрдВред рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╕рднреА рдЬрд╛рд░ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЕрдЧрд▓реЗ рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ рдкрд░ рдЬрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╕ рдХреЙрдкреА рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдЖрдкрдХреЗ рдЯреНрд░рд╛рдВрд╕рдлрд╝реЙрд░реНрдорд░ build/intermediates/transforms/YourTransform/...
рдХреА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдП build/intermediates/transforms/YourTransform/...
рд╕рд╣реА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ transformInvocation.outputProvider.getContentLocation
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рд╛рдкреНрдд рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИред transformInvocation.outputProvider.getContentLocation
ред
рдПрдХ рдРрд╕реА рд╡рд┐рдзрд┐ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рдВрд╢реЛрдзрди рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢рд┐рд╖реНрдЯ рдлрд╛рдЗрд▓реЗрдВ рдирд┐рдХрд╛рд▓ рд░рд╣реА рд╣реИ:
private static void transformDir(File input, File dest) { if (dest.exists()) { FileUtils.forceDelete(dest) } FileUtils.forceMkdir(dest) String srcDirPath = input.getAbsolutePath() String destDirPath = dest.getAbsolutePath() for (File file : input.listFiles()) { String destFilePath = file.absolutePath.replace(srcDirPath, destDirPath) File destFile = new File(destFilePath) if (file.isDirectory()) { transformDir(file, destFile) } else if (file.isFile()) { if (file.name.endsWith(".class") && !file.name.endsWith("R.class") && !file.name.endsWith("BuildConfig.class") && !file.name.contains("R\$")) { transformSingleFile(file, destFile) } else { FileUtils.copyFile(file, destFile) } } } }
рдкреНрд░рд╡реЗрд╢ рджреНрд╡рд╛рд░ рдкрд░ рд╣рдореЗрдВ рд╕реНрд░реЛрдд рдХреЛрдб рдФрд░ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреЗ рд╕рд╛рде рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдорд┐рд▓рддреА рд╣реИ рдЬрд╣рд╛рдВ рдЖрдк рд╕рдВрд╢реЛрдзрд┐рдд рдлрд╛рдЗрд▓реЗрдВ рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рд╣рдо рдкреБрдирд░рд╛рд╡рд░реНрддреА рд╕рднреА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рд╡рд░реНрдЧ рдлрд╛рдЗрд▓реЗрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред рдкрд░рд┐рд╡рд░реНрддрди рд╕реЗ рдкрд╣рд▓реЗ, рдЕрднреА рднреА рдПрдХ рдЫреЛрдЯреА рд╕реА рдЬрд╛рдБрдЪ рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдЕрддрд┐рд░рд┐рдХреНрдд рдХрдХреНрд╖рд╛рдУрдВ рдХреЛ рдорд╛рддрдо рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИред
if (file.name.endsWith(".class") && !file.name.endsWith("R.class") && !file.name.endsWith("BuildConfig.class") && !file.name.contains("R\$")) { transformSingleFile(file, destFile) } else { FileUtils.copyFile(file, destFile) }
рдЗрд╕рд▓рд┐рдП рд╣рдо transformSingleFile
рд╡рд┐рдзрд┐ рд╕реЗ рдЬреБрдбрд╝ рдЧрдП, рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╣рдорд╛рд░реА рдореВрд▓ рдпреЛрдЬрдирд╛ рдХреЗ рджреВрд╕рд░реЗ рдкреИрд░рд╛рдЧреНрд░рд╛рдл рдореЗрдВ рдмрд╣рддреА рд╣реИ
рджреВрд╕рд░реЗ, рдЬрдм рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдлрд╛рдЗрд▓реЗрдВ рдорд┐рд▓рддреА рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдХреИрд╕реЗ рдареАрдХ рд╕реЗ рдмрджрд▓рдирд╛ рд╣реИред
рдкрд░рд┐рдгрд╛рдореА рдХрдХреНрд╖рд╛ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рдХрдо рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рд▓рд┐рдП, рдХрдИ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИрдВ: рдЬреЗрд╡рд╕рд┐рд╕реНрдЯ , рдЬреЛ рдЖрдкрдХреЛ рдмрд╛рдпреЛрдЯреЗрдХ рдФрд░ рд╕реНрд░реЛрдд рдХреЛрдб ( рдмрд╛рдпреЛрдЯреЗрдХ рдХреЗ рдЕрдзреНрдпрдпрди рдореЗрдВ рдЧреЛрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ) рдФрд░ рдПрдПрд╕рдПрдо , рдЬреЛ рдЖрдкрдХреЛ рдХреЗрд╡рд▓ рдмрд╛рдИрдЯрдХреЛрдб рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдФрд░ 2 рдЕрд▓рдЧ-рдЕрд▓рдЧ рдПрдкреАрдЖрдИ рд╣реИрдВред
рдореИрдВрдиреЗ ASM рдХрд╛ рд╡рд┐рдХрд▓реНрдк рдЪреБрдирд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдмрд╛рдИрдЯреЗрдХреЛрдб рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рдЧреЛрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рджрд┐рд▓рдЪрд╕реНрдк рдерд╛ рдФрд░ рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдХреЛрд░ рдПрдкреАрдЖрдИ рдПрд╕рдПрдПрдХреНрд╕ рдкрд╛рд░реНрд╕рд░ рд╕рд┐рджреНрдзрд╛рдВрдд рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдлрд╛рдЗрд▓реЛрдВ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдЙрдЪреНрдЪ рдкреНрд░рджрд░реНрд╢рди рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддрд╛ рд╣реИред
transformSingleFile
рд╡рд┐рдзрд┐ рдЪрдпрдирд┐рдд рдлрд╝рд╛рдЗрд▓ рд╕рдВрд╢реЛрдзрди рдЙрдкрдХрд░рдг рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рднрд┐рдиреНрди рд╣реЛ рд╕рдХрддреА рд╣реИред рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдпрд╣ рдмрд╣реБрдд рдЖрд╕рд╛рди рд▓рдЧ рд░рд╣рд╛ рд╣реИ:
private static void transformClass(String inputPath, String outputPath) { FileInputStream is = new FileInputStream(inputPath) ClassReader classReader = new ClassReader(is) ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES) StaterClassVisitor adapter = new StaterClassVisitor(classWriter) classReader.accept(adapter, ClassReader.EXPAND_FRAMES) byte [] newBytes = classWriter.toByteArray() FileOutputStream fos = new FileOutputStream(outputPath) fos.write(newBytes) fos.close() }
рд╣рдо рдПрдХ рдлрд╝рд╛рдЗрд▓ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП ClassWriter
рдмрдирд╛рддреЗ рд╣реИрдВ, рд╣рдо рдПрдХ рдирдИ рдлрд╝рд╛рдЗрд▓ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП ClassWriter
рдмрдирд╛рддреЗ рд╣реИрдВред рдореИрдВ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рд╕реНрдЯреИрдХ рдлрд╝реНрд░реЗрдо рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП ClassWriter.COMPUTE_FRAMES рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ, рдХреНрдпреЛрдВрдХрд┐ рдореИрдВ рд╕реНрдерд╛рдиреАрдп рдФрд░ Args_size (рдмрд╛рдпрдЯреЗрдХреЛрдб рд╢рдмреНрджрд╛рд╡рд▓реА) рдХреЗ рд╕рд╛рде рдЕрдзрд┐рдХ рдпрд╛ рдХрдо рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдЕрднреА рддрдХ рдлрд╝реНрд░реЗрдо рдХреЗ рд╕рд╛рде рдмрд╣реБрдд рдХреБрдЫ рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИред рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдлреНрд░реЗрдо рдХреА рдЧрдгрдирд╛ рдереЛрдбрд╝рд╛ рдзреАрдорд╛ рд╣реИред
рдлрд┐рд░ рдЕрдкрдирд╛ StaterClassVisitor
рдЬреЛ ClassVisitor
рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ ClassVisitor
рдФрд░ ClassVisitor
рдХреЛ рдкрд╛рд╕ рдХрд░реЗред рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рд╣рдорд╛рд░реА рдлрд╝рд╛рдЗрд▓ рд╕рдВрд╢реЛрдзрди рддрд░реНрдХ рдорд╛рдирдХ ClassWriter рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рдЖрд░реЛрдкрд┐рдд рд╣реИред ASM рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ, рд╕рднреА Visitor
рдЗрдХрд╛рдЗрдпрд╛рдБ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдирд┐рд░реНрдорд┐рдд рдХреА рдЬрд╛рддреА рд╣реИрдВред рдЕрдЧрд▓рд╛, рд╣рдо рдирдИ рдлрд╝рд╛рдЗрд▓ рдХреЗ рд▓рд┐рдП рдмрд╛рдЗрдЯреНрд╕ рдХреА рдПрдХ рд╕рд░рдгреА рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдлрд╝рд╛рдЗрд▓ рдЙрддреНрдкрдиреНрди рдХрд░рддреЗ рд╣реИрдВред
рдЕрдзреНрдпрдпрди рдХрд┐рдП рдЧрдП рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЗ рдореЗрд░реЗ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХрд╛ рдФрд░ рд╡рд┐рд╡рд░рдг рдЬрд╛рдПрдЧрд╛ред
рдПрдиреЛрдЯреЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмрдВрдбрд▓ рдореЗрдВ рдмрдЪрдд рд░рд╛рдЬреНрдп
рдЗрд╕рд▓рд┐рдП, рдореИрдВрдиреЗ рдЧрддрд┐рд╡рд┐рдзрд┐ рдХреЛ рдкреБрди: рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рддреЗ рд╕рдордп рдмрдВрдбрд▓ рдореЗрдВ рдбреЗрдЯрд╛ рд╕реНрдЯреЛрд░реЗрдЬ рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдХрд╛ рдХрд╛рд░реНрдп рд╕реНрд╡рдпрдВ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рд╣реИред рдореИрдВ рд╕рдм рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛:
public class MainActivityJava extends AppCompatActivity { @State private int savedInt = 0;
рд▓реЗрдХрд┐рди рдЕрднреА рдХреЗ рд▓рд┐рдП, рджрдХреНрд╖рддрд╛ рдХреЛ рдЕрдзрд┐рдХрддрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдРрд╕рд╛ рдХрд┐рдпрд╛ (рдореИрдВ рдЖрдкрдХреЛ рдмрддрд╛рдКрдВрдЧрд╛ рдХрд┐ рдмрд╛рдж рдореЗрдВ рдХреНрдпреЛрдВ):
@Stater public class MainActivityJava extends AppCompatActivity { @State(StateType.INT) private int savedInt = 0;
рдФрд░ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ! рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдмрд╛рдж, MainActivityJava
рдХреЛрдб рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
@Stater public class MainActivityJava extends AppCompatActivity { @State(StateType.INT) private int savedInt = 0; protected void onCreate(@Nullable Bundle savedInstanceState) { if (savedInstanceState != null) { this.savedInt = savedInstanceState.getInt("com/example/stater/MainActivityJava_savedInt"); } super.onCreate(savedInstanceState); } protected void onSaveInstanceState(@NonNull Bundle outState) { outState.putInt("com/example/stater/MainActivityJava_savedInt", this.savedInt); super.onSaveInstanceState(outState); }
рд╡рд┐рдЪрд╛рд░ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ, рдЖрдЗрдП рдХреНрд░рд┐рдпрд╛рдиреНрд╡рдпрди рдкрд░ рдЖрдЧреЗ рдмрдврд╝реЗрдВред
рдХреЛрд░ рдПрдкреАрдЖрдИ рдЖрдкрдХреЛ рдкреВрд░реА рдХрдХреНрд╖рд╛ рдлрд╝рд╛рдЗрд▓ рдХреА рдкреВрд░реА рд╕рдВрд░рдЪрдирд╛ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИ, рд╣рдореЗрдВ рдХреБрдЫ рддрд░реАрдХреЛрдВ рдореЗрдВ рд╕рднреА рдЖрд╡рд╢реНрдпрдХ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрджрд┐ рдЖрдк StaterClassVisitor
рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ visit
рд╡рд┐рдзрд┐ рдореЗрдВ рд╣рдореЗрдВ рдХрдХреНрд╖рд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдорд┐рд▓рддреА рд╣реИ, StaterClassVisitor
рд╣рдо StaterClassVisitor
рдХрд┐ рдХреНрдпрд╛ рд╣рдорд╛рд░реА рдХрдХреНрд╖рд╛ @Stater
рдПрдиреЛрдЯреЗрд╢рди рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рд╣реИ рдпрд╛ рдирд╣реАрдВред
рддрдм рд╣рдорд╛рд░рд╛ ClassVisitor
рдХреНрд▓рд╛рд╕ рдХреЗ рд╕рднреА рдХреНрд╖реЗрддреНрд░реЛрдВ рд╕реЗ visitField
рд╣реИ, visitField
рд╡рд┐рдзрд┐ рдХреЛ visitField
рд╣реИ, рдЕрдЧрд░ рдХреНрд▓рд╛рд╕ рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рддреЛ рд╣рдорд╛рд░реЗ StaterFieldVisitor
:
@Override FieldVisitor visitField(int access, String name, String descriptor, String signature, Object value) { FieldVisitor fv = super.visitField(access, name, descriptor, signature, value) if (needTransform) { return new StaterFieldVisitor(fv, name, descriptor, owner) } return fv }
StaterFieldVisitor
@State
рдПрдиреЛрдЯреЗрд╢рди рдХреЗ рд▓рд┐рдП рдЬрд╛рдБрдЪ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдмрджрд▓реЗ рдореЗрдВ, StateAnnotationVisitor
рдХреЛ visitAnnotation
рд╡рд┐рдзрд┐ рдореЗрдВ visitAnnotation
рд╣реИ:
@Override AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { AnnotationVisitor av = super.visitAnnotation(descriptor, visible) if (descriptor == Descriptors.STATE) { return new StateAnnotationVisitor(av, this.name, this.descriptor, this.owner) } return av }
рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдмрдЪрдд / рдмрд╣рд╛рд▓реА рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреА рд╕реВрдЪреА рдмрдирд╛рддрд╛ рд╣реИ:
@Override void visitEnum(String name, String descriptor, String value) { String typeString = (String) value SaverField field = new SaverField(this.name, this.descriptor, this.owner, StateType.valueOf(typeString)) Const.stateFields.add(field) super.visitEnum(name, descriptor, value) }
рдпрд╣ рд╣рдорд╛рд░реЗ рдЖрдЧрдВрддреБрдХреЛрдВ рдХреА рдкреЗрдбрд╝ рдЬреИрд╕реА рд╕рдВрд░рдЪрдирд╛ рдХреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ, рдЬреЛ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдПрдХ рдмрдЪрдд рд╕реНрдерд┐рддрд┐ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рднреА рд╕реВрдЪрдирд╛рдУрдВ рдХреЗ рд╕рд╛рде SaverField SaverField
рдХреА рдПрдХ рд╕реВрдЪреА рдмрдирд╛рддреЗ SaverField
ред
рдЕрдЧрд▓рд╛, рд╣рдорд╛рд░рд╛ ClassVisitor
рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ ClassVisitor
рд╢реБрд░реВ рдХрд░ рджреЗрддрд╛ рд╣реИ рдФрд░ onSaveInstanceState
рдФрд░ onSaveInstanceState
ред рдпрджрд┐ рдХреЛрдИ рд╡рд┐рдзрд┐ рдирд╣реАрдВ рдорд┐рд▓рддреА рд╣реИ, рддреЛ visitEnd
(рдФрд░ рдкреВрд░реА рдХрдХреНрд╖рд╛ рдЙрддреНрддреАрд░реНрдг рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ) рд╡реЗ рдЦрд░реЛрдВрдЪ рд╕реЗ рдЙрддреНрдкрдиреНрди рд╣реЛрддреЗ рд╣реИрдВред
рдмрд╛рдИрдЯрдХреЛрдб рдХрд╣рд╛рдБ рд╣реИ?
рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рд╣рд┐рд╕реНрд╕рд╛ рдХрдХреНрд╖рд╛рдУрдВ рдореЗрдВ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ OnCreateVisitor
рдФрд░ OnSavedInstanceStateVisitor
ред рдмрд╛рдЗрдЯреЗрдХреЛрдб рдХреЗ рд╕рд╣реА рд╕рдВрд╢реЛрдзрди рдХреЗ рд▓рд┐рдП, рдЗрд╕рдХреА рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдХрдо рд╕реЗ рдХрдо рдереЛрдбрд╝рд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдПрдПрд╕рдПрдо рдХреЗ рд╕рднреА рддрд░реАрдХреЗ рдФрд░ рдСрдкрдХреЛрдб рдмреИрдЯрдХреЛрдб рдХреЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЗ рд╕рдорд╛рди рд╣реИрдВ, рдпрд╣ рдЖрдкрдХреЛ рд╕рдорд╛рди рдЕрд╡рдзрд╛рд░рдгрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
onCreate
рд╡рд┐рдзрд┐ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдФрд░ рдЗрд╕реЗ рдЙрддреНрдкрдиреНрди рдХреЛрдб рдХреЗ рд╕рд╛рде рддреБрд▓рдирд╛ рдХрд░реЗрдВ:
if (savedInstanceState != null) { this.savedInt = savedInstanceState.getInt("com/example/stater/MainActivityJava_savedInt"); }
рд╢реВрдиреНрдп рдХреЗ рд▓рд┐рдП рдПрдХ рдмрдВрдбрд▓ рдХреА рдЬрд╛рдБрдЪ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдирд┐рд░реНрджреЗрд╢реЛрдВ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ:
Label l1 = new Label() mv.visitVarInsn(Opcodes.ALOAD, 1) mv.visitJumpInsn(Opcodes.IFNULL, l1)
рд╕рд░рд▓ рд╢рдмреНрджреЛрдВ рдореЗрдВ:
- рдПрдХ рд▓реЗрдмрд▓ l1 рдмрдирд╛рдПрдВ (рдмрд╕ рдПрдХ рд▓реЗрдмрд▓ рдЬрд┐рд╕реЗ рдЖрдк рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ)ред
- рд╣рдо 1 рдХреЗ рд╕рд╛рде рд╕рдВрджрд░реНрдн рдЪрд░ рдХреЛ рдореЗрдореЛрд░реА рдореЗрдВ рд▓реЛрдб рдХрд░рддреЗ рд╣реИрдВред рдЪреВрдВрдХрд┐ рдЗрдВрдбреЗрдХреНрд╕ 0 рд╣рдореЗрд╢рд╛ рдЗрд╕ рдХреЗ рд╕рдВрджрд░реНрдн рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ, рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ 1 рддрд░реНрдХ рдореЗрдВ
Bundle
рдХрд╛ рд╕рдВрджрд░реНрдн рд╣реИред - рд╢реВрдиреНрдп рд╕реНрд╡рдпрдВ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддрд╛ рд╣реИ рдФрд░ l1 рд▓реЗрдмрд▓ рдкрд░ рдЧреЛрдЯреЛ рд╕реНрдЯреЗрдЯрдореЗрдВрдЯред рдмрдВрдбрд▓ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж
visitLabel(l1)
рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдмрдВрдбрд▓ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп, рд╣рдо рдЙрддреНрдкрдиреНрди рдлрд╝реАрд▓реНрдбреНрд╕ рдХреА рд╕реВрдЪреА рдкрд░ рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ PUTFIELD
рдирд┐рд░реНрджреЗрд╢ - рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рдХреЛ рдПрдХ рд╡реИрд░рд┐рдПрдмрд▓ рдкрд░ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВред рдЖрдЗрдП рдХреЛрдб рджреЗрдЦреЗрдВ:
mv.visitVarInsn(Opcodes.ALOAD, 0) mv.visitVarInsn(Opcodes.ALOAD, 1) mv.visitLdcInsn(field.key) final StateType type = MethodDescriptorUtils.primitiveIsObject(field.descriptor) ? StateType.SERIALIZABLE : field.type MethodDescriptor methodDescriptor = MethodDescriptorUtils.getDescriptorByType(type, true) if (methodDescriptor == null || !methodDescriptor.isValid()) { throw new IllegalStateException("StateType for ${field.name} in ${field.owner} is unknown!") } mv.visitMethodInsn( Opcodes.INVOKEVIRTUAL, Types.BUNDLE, methodDescriptor.method, "(${Descriptors.STRING})${methodDescriptor.descriptor}", false )
MethodDescriptorUtils.primitiveIsObject
- рдпрд╣рд╛рдВ рд╣рдо MethodDescriptorUtils.primitiveIsObject
рдХрд┐ рд╡реЗрд░рд┐рдПрдмрд▓ рдореЗрдВ рдПрдХ рд░реИрдкрд░ рдЯрд╛рдЗрдк рд╣реИ, рдпрджрд┐ рд╣рд╛рдВ, рддреЛ рд╡реЗрд░рд┐рдПрдмрд▓ рдЯрд╛рдЗрдк рдХреЛ Serializable
рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рдлрд┐рд░ рдмрдВрдбрд▓ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рддреЛ рдбрд╛рд▓реА рдЬрд╛рддреА рд╣реИ рдФрд░ рдПрдХ рдЪрд░ рдХреЛ рд╕реМрдВрдкрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдпрд╣ рд╕рдм рд╣реИ, onSavedInstanceState
рдкрджреНрдзрддрд┐ рдореЗрдВ рдХреЛрдб рдкреАрдврд╝реА рдПрдХ рд╕рдорд╛рди рддрд░реАрдХреЗ рд╕реЗ рд╣реЛрддреА рд╣реИ, рдЙрджрд╛рд╣рд░рдг ред
рдЖрдкрдХреЛ рдХрд┐рди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рдкрдбрд╝рд╛?- рдкрд╣рд▓рд╛
@Stater
рдПрдиреЛрдЯреЗрд╢рди рдХреЛ @Stater
ред рдЖрдкрдХреА рдЧрддрд┐рд╡рд┐рдзрд┐ / рд╡рд┐рдЦрдВрдбрди рдХреЛ рдХреБрдЫ BaseActivity
рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ рд░рд╛рдЬреНрдп рдХреЛ рдмрдЪрд╛рдиреЗ рдпрд╛ рди рдХрд░рдиреЗ рдХреА рд╕рдордЭ рдХреЛ рдмрд╣реБрдд рдЬрдЯрд┐рд▓ рдХрд░рддрд╛ рд╣реИред рдЖрдкрдХреЛ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рд╡рд░реНрдЧ рдХреЗ рд╕рднреА рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЗ рдКрдкрд░ рдЬрд╛рдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдЧрддрд┐рд╡рд┐рдзрд┐ рд╣реИред рдпрд╣ рд╕рдВрдХрд▓рдХ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рднреА рдХрдо рдХрд░ рд╕рдХрддрд╛ рд╣реИ (рднрд╡рд┐рд╖реНрдп рдореЗрдВ @Stater
рдПрдиреЛрдЯреЗрд╢рди рд╕реЗ рд╕рдмрд╕реЗ рдкреНрд░рднрд╛рд╡реА рдврдВрдЧ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдХрд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИ)ред - рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ
StateType
рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░рдг рдкрд╣рд▓реЗ StateType
рдХрд╛ рдХрд╛рд░рдг рд╣реИред рдЖрдкрдХреЛ рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдХрдХреНрд╖рд╛ рдХреЛ рдФрд░ рдЕрдзрд┐рдХ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ Parcelable
рдпрд╛ Serializable
ред рд▓реЗрдХрд┐рди рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ StateType
:) рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдХреЗ рд╡рд┐рдЪрд╛рд░ рд╣реИрдВред
рдкреНрд░рджрд░реНрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛ рд╕рд╛
рд╕рддреНрдпрд╛рдкрди рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ 10 ./gradlew :app:clean :app:assembleDebug
, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдореЗрдВ 46 рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕реНрдЯреЛрд░ рдХрд┐рдП рдЧрдП рдлрд╝реАрд▓реНрдбреНрд╕ рд╣реИрдВ, рдЬреЛ рдХрдорд╛рдВрдб рдкрд░ рдЪреЗрдХ рдХрд┐рдП рдЧрдП рд╣реИрдВ ./gradlew :app:clean :app:assembleDebug
ред рдореЗрд░реЗ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рд▓рд┐рдП рд▓рд┐рдпрд╛ рдЧрдпрд╛ рд╕рдордп 108 рд╕реЗ 200 рдПрдордПрд╕ рддрдХ рд╣реИред
рдЯрд┐рдкреНрд╕
рдпрджрд┐ рдЖрдк рдкрд░рд┐рдгрд╛рдореА рдмрд╛рдпреЛрдЯреЗрдХ рдХреЛ рджреЗрдЦрдиреЗ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЕрдкрдиреА рд░реВрдкрд╛рдВрддрд░рдг рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ TraceClassVisitor
(ASM рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЧрдпрд╛) рдХреЛ рдХрдиреЗрдХреНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
private static void transformClass(String inputPath, String outputPath) { ... TraceClassVisitor traceClassVisitor = new TraceClassVisitor(classWriter, new PrintWriter(System.out)) StaterClassVisitor adapter = new StaterClassVisitor(traceClassVisitor) ... }
рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ TraceClassVisitor
рдЙрд╕ рд╡рд░реНрдЧ рдХреЗ рд╕рдВрдкреВрд░реНрдг рдмрд╛рдпреЛрдЯреЗрдХ рд╕рд╛рдВрддреНрд╡рдирд╛ рдХреЛ рд╕рд╛рдВрддреНрд╡рдирд╛ рджреЗрдЧрд╛ рдЬреЛ рдЗрд╕рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрд╛рд░рд┐рдд рд╣реБрдЖ, рдбрд┐рдмрдЧрд┐рдВрдЧ рдЪрд░рдг рдореЗрдВ рдПрдХ рдмрд╣реБрдд рд╣реА рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдЙрдкрдпреЛрдЧрд┐рддрд╛ред
рдпрджрд┐ рдмрд╛рдпрдЯреЗрдХреЛрдб рдХреЛ рдЧрд▓рдд рддрд░реАрдХреЗ рд╕реЗ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рддреЛ рдмрд╣реБрдд рд╣реА рд╕рдордЭ рд╕реЗ рдмрд╛рд╣рд░ рдХреА рддреНрд░реБрдЯрд┐рдпрд╛рдВ рдЙрдбрд╝ рдЬрд╛рддреА рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рд╕рдВрднрд╡ рд╣реЛ рддреЛ рдХреЛрдб рдХреЗ рд╕рдВрднрд╛рд╡рд┐рдд рдЦрддрд░рдирд╛рдХ рд╡рд░реНрдЧреЛрдВ рдХреЛ рд▓реЙрдЧ рдХрд░рдирд╛ рдпрд╛ рдЕрдкрдиреЗ рдЕрдкрд╡рд╛рдж рдЙрддреНрдкрдиреНрди рдХрд░рдирд╛ рд╕рд╛рд░реНрдердХ рд╣реИред
рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рджреЗрдирд╛
рд╕реНрд░реЛрдд рдХреЛрдб рдХрд╛ рд╕рдВрд╢реЛрдзрди рдПрдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдЙрдкрдХрд░рдг рд╣реИред рдЗрд╕рдХреЗ рд╕рд╛рде, рдЖрдк рдХрдИ рд╡рд┐рдЪрд╛рд░реЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд░рдХреНрд╖рдХ, рдХреНрд╖реЗрддреНрд░, рд░реВрдмреНрд░реЛрдЗрд▓реЗрдХреНрдЯреНрд░рд┐рдХ рдФрд░ рдЕрдиреНрдп рдврд╛рдВрдЪреЗ рдЗрд╕ рд╕рд┐рджреНрдзрд╛рдВрдд рдкрд░ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред AOP рдХреЛрдб рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рд▓рд┐рдП рднреА рд╕рдЯреАрдХ рд░реВрдк рд╕реЗ рдзрдиреНрдпрд╡рд╛рдж рд╕рдВрднрд╡ рд╣реИред
рдФрд░ рдмрд╛рдЗрдЯрдХреЛрдб рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдЬреНрдЮрд╛рди рдбреЗрд╡рд▓рдкрд░ рдХреЛ рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдХрд┐ рдЙрд╕рдиреЗ рдЬреЛ рдХреЛрдб рд▓рд┐рдЦрд╛ рдерд╛ рд╡рд╣ рдЕрдВрдд рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рд╣реИред рдФрд░ рдЬрдм рдпрд╣ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХреЛрдб, рдЬрд╛рд╡рд╛ рдпрд╛ рдХреЛрдЯрд▓рд┐рди рдореЗрдВ рдХрд┐рд╕ рднрд╛рд╖рд╛ рдореЗрдВ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╕реАрдзреЗ рдмрд╛рдпреЛрдЯреЗрдХ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред
рдпрд╣ рд╡рд┐рд╖рдп рдореБрдЭреЗ рдмрд╣реБрдд рд░реЛрдЪрдХ рд▓рдЧрд╛, Google рд╕реЗ рдЯреНрд░рд╛рдВрд╕рдлрд╝реЙрд░реНрдо рдПрдкреАрдЖрдИ рдХреЛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рддреЗ рд╕рдордп рдореБрдЦреНрдп рдХрдард┐рдирд╛рдЗрдпрд╛рдБ рдереАрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╡реЗ рд╡рд┐рд╢реЗрд╖ рдкреНрд░рд▓реЗрдЦрди рдФрд░ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рдХреГрдкрдпрд╛ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рдПрдПрд╕рдПрд╕рдПрдо, рдЯреНрд░рд╛рдВрд╕рдлреЙрд░реНрдо рдПрдкреАрдЖрдИ рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЙрддреНрдХреГрд╖реНрдЯ рдкреНрд░рд▓реЗрдЦрди рд╣реИ, рдЬрд┐рд╕рдореЗрдВ 150 рдкреГрд╖реНрдареЛрдВ рдХреЗ рд╕рд╛рде рдкреАрдбреАрдПрдл рдлрд╛рдЗрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдмрд╣реБрдд рд╡рд┐рд╕реНрддреГрдд рдорд╛рд░реНрдЧрджрд░реНрд╢рд┐рдХрд╛ рд╣реИред рдФрд░, рдЪреВрдВрдХрд┐ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЗ рддрд░реАрдХреЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдмрд╛рдпреЛрдЯреЗрдХ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЗ рдмрд╣реБрдд рд╕рдорд╛рди рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЧрд╛рдЗрдб рджреЛрдЧреБрдирд╛ рдЙрдкрдпреЛрдЧреА рд╣реИред
рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдкрд░рд┐рд╡рд░реНрддрди, рдмрд╛рдЗрдЯрдХреЛрдб рдореЗрдВ рдореЗрд░реЗ рд╡рд┐рд╕рд░реНрдЬрди рдкрд░ рд╣реИ, рдФрд░ рдпрд╣ рд╕рдм рдЦрддреНрдо рдирд╣реАрдВ рд╣реБрдЖ рд╣реИ, рдореИрдВ рдЕрдзреНрдпрдпрди рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦреВрдВрдЧрд╛ рдФрд░ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдХреБрдЫ рдФрд░ рд▓рд┐рдЦреВрдВред
рд╕рдВрджрд░реНрдн
рдЧрд┐рдердм рдЙрджрд╛рд╣рд░рдг
рдПрдПрд╕рдПрдо
рд╣реИрдмреНрд░реЗрдЯ рд▓реЗрдЦ bytecode рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ
рдмрд╛рдпрдЯреЗрдХреЛрдб рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛ рдФрд░
рдЯреНрд░рд╛рдВрд╕рдлрд╝реЙрд░реНрдо рдПрдкреАрдЖрдИ
рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ, рдкреНрд░рд▓реЗрдЦрди рдкрдврд╝рдирд╛