Android рдХреЛрдб рдкрд░рд┐рд╡рд░реНрддрди


рдЬреНрд╡рд╛рдЗрди рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп


рдпрд╣ рд╕рдм рдЗрд╕ рддрдереНрдп рд╕реЗ рд╢реБрд░реВ рд╣реБрдЖ рдерд╛ рдХрд┐ рдореИрдВ рдПрдВрдбреНрд░реЙрдЗрдб рд╡рд┐рдХрд╛рд╕ (рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ) рдореЗрдВ рдЗрд╕рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдЧреНрд░реИрдбрд▓ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреА рд╕реВрдХреНрд╖реНрдорддрд╛рдУрдВ рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ред рдореИрдВрдиреЗ рдЬреАрд╡рди рдЪрдХреНрд░ рдФрд░ рдкреБрд╕реНрддрдХреЛрдВ рдХреЗ рд╕рд╛рде рд╢реБрд░реБрдЖрдд рдХреА, рдзреАрд░реЗ-рдзреАрд░реЗ рд╕рд░рд▓ рдХрд╛рд░реНрдп рд▓рд┐рдЦреЗ, рдЕрдкрдирд╛ рдкрд╣рд▓рд╛ рдЧреНрд░реИрдбрд▓ рдкреНрд▓рдЧрдЗрди рдмрдирд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА ( рдмрд┐рд▓реНрдбрд╕реНрдХреИрди рдореЗрдВ ) рдФрд░ рдлрд┐рд░ рдпрд╣ рд╢реБрд░реВ рд╣реБрдЖред


рдПрдВрдбреНрд░реЙрдЗрдб рд╡рд┐рдХрд╛рд╕ рдХреА рд╡рд╛рд╕реНрддрд╡рд┐рдХ рджреБрдирд┐рдпрд╛ рдХреЗ рдХрд░реАрдм рдХреБрдЫ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓реЗрддреЗ рд╣реБрдП, рдЙрдиреНрд╣реЛрдВрдиреЗ рдПрдХ рдкреНрд▓рдЧрдЗрди рд▓рд┐рдЦрд╛, рдЬреЛ xml рдорд╛рд░реНрдХрдЕрдк рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рд▓реЗрдЖрдЙрдЯ рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╡рд┐рдЪрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдВрдХ рдХреЗ рд╕рд╛рде рдЙрди рдкрд░ рдПрдХ рдЬрд╛рд╡рд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рддрд╛ рд╣реИред рддрдм рдЙрдиреНрд╣реЛрдВрдиреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдирд┐рдлрд╝реЗрд╕реНрдЯ (рдпрд╣ рдХрд╛рд░реНрдп рдбреНрд░рд╛рдлреНрдЯ рдкрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдерд╛) рдХреЗ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдмрд╛рдж рд▓рд┐рдпрд╛, рдХреНрдпреЛрдВрдХрд┐ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдмрд╛рдж рдкреНрд░рдХрдЯрди рдореЗрдВ рд▓рдЧрднрдЧ 5k рд▓рд╛рдЗрдиреЗрдВ рд▓рдЧреАрдВ, рдФрд░ рдЗрд╕ рддрд░рд╣ рдХреА xml рдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рде IDE рдореЗрдВ рдХрд╛рдо рдХрд░рдирд╛ рдХрд╛рдлреА рдореБрд╢реНрдХрд┐рд▓ рд╣реИред


рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдкрддрд╛ рдЪрд▓рд╛ рдХрд┐ рдПрдВрдбреНрд░реЙрдЗрдб рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдФрд░ рд╕рдВрд╕рд╛рдзрди рдХреИрд╕реЗ рдЙрддреНрдкрдиреНрди рд╣реЛрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╕рдордп рдХреЗ рд╕рд╛рде рдореБрдЭреЗ рдХреБрдЫ рдФрд░ рдЪрд╛рд╣рд┐рдП рдерд╛ред рдПрдХ рд╡рд┐рдЪрд╛рд░ рдерд╛ рдХрд┐ рдПрдПрд╕рдЯреА (рдПрдмреНрд╕рдЯреНрд░реИрдХреНрдЯ рд╕рд┐рдВрдЯреЗрдХреНрд╕ рдЯреНрд░реА) рдХреЛ рд╕рдВрдХрд▓рди рдХреЗ рд╕рдордп рдореЗрдВ рдардВрдбрд╛ рдХрд░рдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдЧреНрд░реВрд╡реА рдмреЙрдХреНрд╕ рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рддрд╛ рд╣реИ ред рдЗрд╕ рддрд░рд╣ рдХреЗ рд░реВрдкрд╛рдВрддрд░реЛрдВ рд╕реЗ рдХрдИ рд╕рдВрднрд╛рд╡рдирд╛рдПрдБ рдЦреБрд▓рддреА рд╣реИрдВ, рдПрдХ рдХрд▓реНрдкрдирд╛ рд╣реЛрдЧреАред


рдЗрд╕рд▓рд┐рдП рдХрд┐ рд╕рд┐рджреНрдзрд╛рдВрдд рд╕рд┐рд░реНрдл рдПрдХ рд╕рд┐рджреНрдзрд╛рдВрдд рдирд╣реАрдВ рдерд╛, рдореИрдВрдиреЗ рдПрдВрдбреНрд░реЙрдЗрдб рд╡рд┐рдХрд╛рд╕ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рдХреБрдЫ рдХреЗ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд╕рд╛рде рд╡рд┐рд╖рдп рдХреЗ рдЕрдзреНрдпрдпрди рдХреЛ рд╕реБрджреГрдврд╝ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ред рдкрд╣рд▓реА рдмрд╛рдд рдЬреЛ рджрд┐рдорд╛рдЧ рдореЗрдВ рдЖрдИ рд╡рд╣ рдереА, рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдкреБрд░реНрдЬрд╝реЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рдмрдирд╛рдирд╛ред рдореЛрдЯреЗ рддреМрд░ рдкрд░, рдмрдВрдбрд▓ рдореЗрдВ рдмрдЪрдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЪрд░ рдиреНрдпреВрдирддрдо рдмреЙрдпрд▓рд░рдкреНрд▓реЗрдЯ рдХреЗ рд╕рд╛рде рдпрдерд╛рд╕рдВрднрд╡ рд╕рд░рд▓ рд╣реИрдВред


рдХрд╣рд╛рдБ рд╕реЗ рд╢реБрд░реВ рдХрд░реЗрдВ?


  1. рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЖрдкрдХреЛ рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдПрдВрдбреНрд░реЙрдЗрдб рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдЧреНрд░реИрдбрд▓ рдЬреАрд╡рди рдЪрдХреНрд░ рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдлрд╛рдЗрд▓реЛрдВ рддрдХ рдХреИрд╕реЗ рдкрд╣реБрдВрдЪрд╛ рдЬрд╛рдП, рдЬрд┐рд╕реЗ рд╣рдо рдмрд╛рдж рдореЗрдВ рдмрджрд▓ рджреЗрдВрдЧреЗред
  2. рджреВрд╕рд░реЗ, рдЬрдм рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рдлрд╛рдЗрд▓реЗрдВ рдорд┐рд▓рддреА рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдХреИрд╕реЗ рдареАрдХ рд╕реЗ рдмрджрд▓рдирд╛ рд╣реИред

рдЪрд▓рд┐рдП рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ:


рд╕рдВрдХрд▓рди рд╕рдордп рдкрд░ рдлрд╝рд╛рдЗрд▓реЛрдВ рддрдХ рдкрд╣реБрдБрдЪреЗрдВ


рдЪреВрдВрдХрд┐ рд╣рдо рд╕рдВрдХрд▓рди рд╕рдордп рдкрд░ рдлрд╛рдЗрд▓реЗрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдПрдХ рдЧреНрд░реИрдбрд▓ рдкреНрд▓рдЧрдЗрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдлрд╛рдЗрд▓реЛрдВ рдХреЛ рд░реЛрдХ рджреЗрдЧрд╛ рдФрд░ рдкрд░рд┐рд╡рд░реНрддрди рд╕реЗ рдирд┐рдкрдЯреЗрдЧрд╛ред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдкреНрд▓рдЧрдЗрди рдЬрд┐рддрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рдЙрддрдирд╛ рд╕рд░рд▓ рд╣реИред рд▓реЗрдХрд┐рди рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВ рдЖрдкрдХреЛ рджрд┐рдЦрд╛рддрд╛ рд╣реВрдБ рдХрд┐ рдкреНрд▓рдЧрдЗрди рдХреЗ рд╕рд╛рде 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' } 

  1. apply plugin: 'java-gradle-plugin' рдХрд╣рдирд╛ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдореЙрдбреНрдпреВрд▓ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдПрдХ рдврд╛рд▓ рдкреНрд▓рдЧрдЗрди рд╣реИред
  2. apply plugin: 'groovy' рдЗрд╕ рдкреНрд▓рдЧрдЗрди рдХреЛ рдЦрд╛рдВрдЪреЗ рдкрд░ рд▓рд┐рдЦрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИ (рдпрд╣ рдпрд╣рд╛рдВ рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛, рдЖрдк рдХрдо рд╕реЗ рдХрдо Groovy, рдХрдо рд╕реЗ рдХрдо рдЬрд╛рд╡рд╛, рдХрдо рд╕реЗ рдХрдо Kotlin, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЪрд╛рд╣реЗрдВ) рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВред рдореИрдВ рдореВрд▓ рд░реВрдк рд╕реЗ рдЦрд╛рдВрдЪреЗ рдкрд░ рдкреНрд▓рдЧрдЗрдиреНрд╕ рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдореЗрдВ рдЧрддрд┐рд╢реАрд▓ рдЯрд╛рдЗрдкрд┐рдВрдЧ рд╣реИ рдФрд░ рдХрднреА-рдХрднреА рдпрд╣ рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдпрджрд┐ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рддреЛ рдЖрдк рдмрд╕ @TypeChecked рдПрдиреЛрдЯреЗрд╢рди рдбрд╛рд▓ рд╕рдХрддреЗ рд╣реИрдВред
  3. implementation gradleApi() - implementation gradleApi() рдПрдкреАрдЖрдИ рдирд┐рд░реНрднрд░рддрд╛ рдХреЛ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ рддрд╛рдХрд┐ org.gradle.api.Plugin , org.gradle.api.Project , рдЖрджрд┐ рддрдХ рдкрд╣реБрдВрдЪ рд╣реЛред
  4. рдПрдВрдбреНрд░реЙрдЗрдб рдкреНрд▓рдЧрдЗрди рдХреА рд╕рдВрд╕реНрдерд╛рдУрдВ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП 'com.android.tools.build:gradle:3.5.0' рдФрд░ 'com.android.tools.build:gradle-api:3.5.0' рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
  5. '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) рд╣реЛрдЧрд╛ред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдореБрдЭреЗ рдЗрд╕ рд╡рд┐рдзрд┐ рдХреЗ рд╕рд╛рде рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╡рд┐рд╡рд░рдг рдирд╣реАрдВ рдорд┐рд▓рд╛, рдореБрдЭреЗ рдХреЗрд╡рд▓ рдЪреАрдиреА рд▓реЗрдЦ рдФрд░ рд╡рд┐рд╢реЗрд╖ рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдХреЗ рдмрд┐рдирд╛ рдХреБрдЫ рдЙрджрд╛рд╣рд░рдг рдорд┐рд▓реЗ, рдпрд╣рд╛рдВ рдПрдХ рд╡рд┐рдХрд▓реНрдк рд╣реИред


рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд░рддреЗ рд╕рдордп рдореИрдВрдиреЗ рдЬреЛ рд╕рдордЭрд╛ рдерд╛:


  1. рд╕рднреА рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ рдЪреЗрди рдЕрд╕реЗрдВрдмрд▓реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдЭреБрдХреЗ рд╣реБрдП рд╣реИрдВред рдпрд╣реА рд╣реИ, рдЖрдк рддрд░реНрдХ рд▓рд┐рдЦреЗрдВрдЧреЗ рдЬреЛ рд╣реЛрдЧрд╛ рдирд┐рдЪреЛрдбрд╝рд╛ рд╣реБрдЖ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕реНрдерд╛рдкрд┐рдд рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВред рдЖрдкрдХреЗ рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ рдХреЗ рдмрд╛рдж, рдПрдХ рдФрд░ рдХрд╛рдо рдХрд░реЗрдЧрд╛, рдЖрджрд┐ред
  2. рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг: рднрд▓реЗ рд╣реА рдЖрдк рдХрд┐рд╕реА рднреА рдлрд╝рд╛рдЗрд▓ рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдирд╣реАрдВ рдмрдирд╛рддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдЙрди рдЬрд╛рд░ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдмрджрд▓рдирд╛ рдирд╣реАрдВ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдЬреЛ рдЖрдкрдХреЗ рдкрд╛рд╕ рдЖрдПрдВрдЧреА, рдлрд┐рд░ рднреА рдЙрдиреНрд╣реЗрдВ рдмрджрд▓рдиреЗ рдХреЗ рдмрд┐рдирд╛ рдЖрдкрдХреА рдЖрдЙрдЯрдкреБрдЯ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рдХреЙрдкреА рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрд╣ рдЖрдЗрдЯрдо рдкрд╣рд▓реЗ рд╕реЗ рдЕрдиреБрд╕рд░рдг рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рдлрд╝рд╛рдЗрд▓ рдХреЛ рдЪреЗрди рдХреЗ рд╕рд╛рде рдХрд┐рд╕реА рдЕрдиреНрдп рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ рдореЗрдВ рдЖрдЧреЗ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЕрдВрдд рдореЗрдВ рдлрд╝рд╛рдЗрд▓ рдмрд╕ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реЛрдЧреАред

рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдХрд┐ рдЯреНрд░рд╛рдВрд╕рдлрд╝реЙрд░реНрдо рд╡рд┐рдзрд┐ рдХреНрдпрд╛ рджрд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП:


 @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) //...      mv.visitLabel(l1) 

рд╕рд░рд▓ рд╢рдмреНрджреЛрдВ рдореЗрдВ:


  1. рдПрдХ рд▓реЗрдмрд▓ l1 рдмрдирд╛рдПрдВ (рдмрд╕ рдПрдХ рд▓реЗрдмрд▓ рдЬрд┐рд╕реЗ рдЖрдк рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ)ред
  2. рд╣рдо 1 рдХреЗ рд╕рд╛рде рд╕рдВрджрд░реНрдн рдЪрд░ рдХреЛ рдореЗрдореЛрд░реА рдореЗрдВ рд▓реЛрдб рдХрд░рддреЗ рд╣реИрдВред рдЪреВрдВрдХрд┐ рдЗрдВрдбреЗрдХреНрд╕ 0 рд╣рдореЗрд╢рд╛ рдЗрд╕ рдХреЗ рд╕рдВрджрд░реНрдн рд╕реЗ рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ, рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ 1 рддрд░реНрдХ рдореЗрдВ Bundle рдХрд╛ рд╕рдВрджрд░реНрдн рд╣реИред
  3. рд╢реВрдиреНрдп рд╕реНрд╡рдпрдВ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддрд╛ рд╣реИ рдФрд░ 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 ) // cast if (type == StateType.SERIALIZABLE || type == StateType.PARCELABLE || type == StateType.PARCELABLE_ARRAY || type == StateType.IBINDER ) { mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getType(field.descriptor).internalName) } mv.visitFieldInsn(Opcodes.PUTFIELD, field.owner, field.name, field.descriptor) 

MethodDescriptorUtils.primitiveIsObject - рдпрд╣рд╛рдВ рд╣рдо MethodDescriptorUtils.primitiveIsObject рдХрд┐ рд╡реЗрд░рд┐рдПрдмрд▓ рдореЗрдВ рдПрдХ рд░реИрдкрд░ рдЯрд╛рдЗрдк рд╣реИ, рдпрджрд┐ рд╣рд╛рдВ, рддреЛ рд╡реЗрд░рд┐рдПрдмрд▓ рдЯрд╛рдЗрдк рдХреЛ Serializable рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рдлрд┐рд░ рдмрдВрдбрд▓ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рддреЛ рдбрд╛рд▓реА рдЬрд╛рддреА рд╣реИ рдФрд░ рдПрдХ рдЪрд░ рдХреЛ рд╕реМрдВрдкрд╛ рдЬрд╛рддрд╛ рд╣реИред


рдпрд╣ рд╕рдм рд╣реИ, onSavedInstanceState рдкрджреНрдзрддрд┐ рдореЗрдВ рдХреЛрдб рдкреАрдврд╝реА рдПрдХ рд╕рдорд╛рди рддрд░реАрдХреЗ рд╕реЗ рд╣реЛрддреА рд╣реИ, рдЙрджрд╛рд╣рд░рдг ред


рдЖрдкрдХреЛ рдХрд┐рди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рдкрдбрд╝рд╛?
  1. рдкрд╣рд▓рд╛ @Stater рдПрдиреЛрдЯреЗрд╢рди рдХреЛ @Stater ред рдЖрдкрдХреА рдЧрддрд┐рд╡рд┐рдзрд┐ / рд╡рд┐рдЦрдВрдбрди рдХреЛ рдХреБрдЫ BaseActivity рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ рд░рд╛рдЬреНрдп рдХреЛ рдмрдЪрд╛рдиреЗ рдпрд╛ рди рдХрд░рдиреЗ рдХреА рд╕рдордЭ рдХреЛ рдмрд╣реБрдд рдЬрдЯрд┐рд▓ рдХрд░рддрд╛ рд╣реИред рдЖрдкрдХреЛ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рд╡рд░реНрдЧ рдХреЗ рд╕рднреА рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЗ рдКрдкрд░ рдЬрд╛рдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдПрдХ рдЧрддрд┐рд╡рд┐рдзрд┐ рд╣реИред рдпрд╣ рд╕рдВрдХрд▓рдХ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рднреА рдХрдо рдХрд░ рд╕рдХрддрд╛ рд╣реИ (рднрд╡рд┐рд╖реНрдп рдореЗрдВ @Stater рдПрдиреЛрдЯреЗрд╢рди рд╕реЗ рд╕рдмрд╕реЗ рдкреНрд░рднрд╛рд╡реА рдврдВрдЧ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдХрд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИ)ред
  2. рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ 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 рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ
рдмрд╛рдпрдЯреЗрдХреЛрдб рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛ рдФрд░
рдЯреНрд░рд╛рдВрд╕рдлрд╝реЙрд░реНрдо рдПрдкреАрдЖрдИ
рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ, рдкреНрд░рд▓реЗрдЦрди рдкрдврд╝рдирд╛

Source: https://habr.com/ru/post/hi469237/


All Articles