在上一篇夹囚,我們已經(jīng)知道了如何創(chuàng)建一個簡單的插件,這一節(jié)將在此基礎(chǔ)上繼續(xù)說說如何配置自己的Transform
厅瞎。
1 轉(zhuǎn)換器 Transform
轉(zhuǎn)換器Transform
是由Google
提供,讓開發(fā)者可以在編譯后,打包前這段時期性芬,進行額外干預(yù)操作母谎,從而提供操作字節(jié)碼的時機瘦黑。
2 創(chuàng)建 Transform
創(chuàng)建自定義的FreeCoderTransform
類,然后繼承至Transform
奇唤。
public class FreeCoderTransform extends Transform {
// 1
@Override
public String getName() {
return "freecoder";
}
// 2
@Override
public Set<QualifiedContent.ContentType> getInputTypes() {
return TransformManager.CONTENT_CLASS;
}
// 3
@Override
public Set<? super QualifiedContent.Scope> getScopes() {
return TransformManager.SCOPE_FULL_PROJECT;
}
// 4
@Override
public boolean isIncremental() {
return false;
}
// 5
@Override
public void transform(TransformInvocation transformInvocation) throws TransformException, InterruptedException, IOException {
Collection<TransformInput> inputs = transformInvocation.getInputs();
TransformOutputProvider outputProvider = transformInvocation.getOutputProvider();
inputs.forEach(transformInput -> {
transformInput.getJarInputs().forEach(jarInput -> {
File dest = outputProvider.getContentLocation(jarInput.getName(), jarInput.getContentTypes(), jarInput.getScopes(), Format.JAR);
try {
FileUtils.copyFile(jarInput.getFile(), dest);
} catch (IOException e) {
e.printStackTrace();
}
});
transformInput.getDirectoryInputs().forEach(directoryInput -> {
File dest = outputProvider.getContentLocation(directoryInput.getName(), directoryInput.getContentTypes(), directoryInput.getScopes(), Format.DIRECTORY);
try {
FileUtils.copyFile(directoryInput.getFile(), dest);
} catch (IOException e) {
e.printStackTrace();
}
});
});
}
}
標(biāo)記1處:對應(yīng)自定義Transform
的Task
名稱幸斥,同步完成后,會顯示在Gradle
控制面板上咬扇,比如:transformClassesWithXXXForDebug
甲葬。
標(biāo)記2、3處:定義了我們將要操作的編譯過程中具體哪些類型的文件懈贺,其中 2 的類型:
CONTENT_CLASS://class 文件
CONTENT_JARS: //jar包经窖,包括class文件與resource資源文件
CONTENT_RESOURCES // resource資源文件
CONTENT_NATIVE_LIBS // 本地libs
CONTENT_DEX // dex文件
CONTENT_DEX_WITH_RESOURCES // dex文件與resource資源文件
標(biāo)記 3 處:表示作用的項目范圍,SCOPE_FULL_PROJECT
表示整個項目梭灿。
標(biāo)記 4 處:表示是否支持增量編譯画侣。
標(biāo)記 5 處:這里是個核心方法,需要覆蓋重寫堡妒,并且按Google
提供的輸出目錄outputProvider
上輸出配乱,否則將這個Transform
引入會報錯。
transformInvocation.getInputs()
獲取編譯后的所有class
文件皮迟,transformInvocation.getOutputProvider()
獲取Google
提供的輸出目錄搬泥,我們把這些編譯后的文件做完處理后,然后再扔向該目錄伏尼,最終參與到打dex
包的過程忿檩。
而后就是簡單的復(fù)制工作,至于處理爆阶,我們下一節(jié)講燥透,這個過程可以實現(xiàn)面向切面的編程代赁。
3 引入 Transform
如下:(接上一節(jié)代碼)
public class FreeCoderPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
final FreeCoderExtension extension = project.getExtensions()
.create("freecoder", FreeCoderExtension.class);
project.afterEvaluate(innerProject -> System.out.println("extension: " + extension.name));
// 創(chuàng)建轉(zhuǎn)換器
FreeCoderTransform freeCoder = new FreeCoderTransform();
// 1
BaseExtension baseExtension = project.getExtensions().getByType(BaseExtension.class);
// 2
baseExtension.registerTransform(freeCoder);
}
}
標(biāo)記1處:BaseExtension
指的就是Android打包過程中,com.android.application
這個插件所包含的擴展兽掰,方便開發(fā)者在打包過程中進行相應(yīng)的干預(yù)芭碍。
標(biāo)記2處:把我們的Transform
注冊進入該擴展中。
到此為止孽尽,我們就配置好了自己的Transform
窖壕,下一節(jié),就來講講如果通過更改字節(jié)碼達到面向切面編程的效果杉女。