USB-C ライトニングケーブル 純正 1M 3本セット【2025新版 MFi認証】 iphone充電ケーブルタイプC 20W対応 PD急速充電 iPhone コード 超高耐久&高速データ同期 for iPhone14/13/12 Pro Max/11/X/8/iPad/AirPods/MacBookなど各種対応
¥999 (2025年4月25日 13:07 GMT +09:00 時点 - 詳細はこちら価格および発送可能時期は表示された日付/時刻の時点のものであり、変更される場合があります。本商品の購入においては、購入の時点で当該の Amazon サイトに表示されている価格および発送可能時期の情報が適用されます。)【2025正規MFi認証品】i-Phone 充電ケーブル ライトニングケーブル 純正品質【1M/2M 各2本】充電器 ケーブル 2.4A急速充電 USB 充電コード 高速データ転送 断線防止 高耐久 i-Phone 14/14 Pro/13/13 Pro/12/11/X/8/8plus/7/6/iPad 各種対応
¥898 (2025年4月25日 13:07 GMT +09:00 時点 - 詳細はこちら価格および発送可能時期は表示された日付/時刻の時点のものであり、変更される場合があります。本商品の購入においては、購入の時点で当該の Amazon サイトに表示されている価格および発送可能時期の情報が適用されます。)
- GoogleのAndroidチームには
Gradle職人
がいる(はず) - Android Gradle Pluginを身体に馴染ませるために職人が用意してくれたサンプルを全部読む
- 各READMEに全部書いていると言えば、それはそう
- 基本は抑えている前提でこんな書き方もありなのか、という観点で読む
agp-8.9
https://github.com/android/gradle-recipes/tree/dd275c878633c4ad272883d4bc70f1ab3c8ed0fa
addBuildTypeUsingDslFinalize
-
AndroidComponentsExtensionを使って、
buildTypes
を追加するサンプル- AndroidComponentsExtensionは実行順序を持っているので、それに合わせて実装してねというもの
- 実行順序については公式のAndroid build flow and extension pointsに書いてある
-
build-login
でAGP全部(com.android.tools.build:gradle
)をimplementationせずにcom.android.tools.build:gradle-api
のみをimplementationしている -
依存解決の量が少ないので初期化が若干早いかも(最終的にビルドするときには本体自体も必要になるので、最終的には同じ)
com.android.tools.build:gradle-api
└── com.android.tools.build:builder-test-api
├── com.android.tools:annotations
├── com.android.tools:common
└── com.android.tools.ddms:ddmlib
addCustomBuildConfigFields
- AndroidComponentsExtensionを使って
BuildConfigField
を追加するサンプル -
buildTypes
やproductFlavors
で追加するコードのほうが良く見かけるがAndroidComponentsExtension登場移行のAGP7系以降のbuild type, product flavor依存のものはAndroidComponentsExtensionに寄せるほうが思想とマッチしているかもしれない - AndroidComponentsExtensionを使うと生成コードにコメントを追加できる
- GradleのProvider APIを使って、
buildConfigField
の値を動的に変更することができる
build.gradle
import com.android.build.api.variant.BuildConfigField
// よくみるやつ:コメント追加不可
android {
buildTypes {
release {
buildConfigField("String", "BUILD_TIME", ""${minutesSinceEpoch}"")
}
debug {
buildConfigField("String", "BUILD_TIME", ""0"")
}
}
}
// AndroidComponentsExtension:コメント追加可
androidComponents.onVariants { variant ->
variant.buildConfigFields.put(
"FloatValue",
new BuildConfigField(
"Float",
"12.0f",
"Float Value Comment"
)
)
}
BuildConfig.java
public final class BuildConfig {
// Float Value Comment
public static final Float FloatValue = 12.0f;
}
addCustomSourceType
- AndroidComponentsExtensionで
registerSourceType
を使って追加するsource typeを宣言する - AGPでは認識されないがAndroidComponentsExtensionで認識されるsource typeを追加することができる
- addStaticSourceDirectory, addGeneratedSourceDirectoryを使って、source typeに追加するsource folderを追加する
- アプリに梱包しないファイル類を管理する際に便利(だが標準のGradle APIを使ってもそんな変わらない気がする)
build.gradle.kts
androidComponents {
registerSourceType("toml")
onVariants { variant ->
variant.sources.getByName("toml").also {
// adding custom folders (static and generated) to `toml` source type
it.addStaticSourceDirectory("third_party/${variant.name}/toml")
it.addGeneratedSourceDirectory(addSourceTaskProvider, AddCustomSources::outputFolder)
}
}
}
- Google Play Services Pluginでも使われている
addGeneratedSourceFolder
- AndroidComponentsExtensionで自動生成ファイルを
assets
に追加するサンプル -
addGeneratedSourceDirectory
を使って、source folderを追加する - サンプルではassetsに追加しているが、
java
やkotlin
のsource folderにも追加できる
addMultipleArtifact
-
com.android.build.api.artifact.MultipleArtifactのサンプル(≒AABにファイルを追加する)
- MultipleArtifact.MULTIDEX_KEEP_PROGUARD: proguardルールを追加する
- MultipleArtifact.NATIVE_DEBUG_METADATA: debug metadata(.dbg)を追加する
- MultipleArtifact.NATIVE_SYMBOL_TABLES: debug symbol tables(.sym)を追加する
-
CheckBundleTask, outputを設定しないとup-to-dateにならないので
使わなくとも宣言している
-
variant.artifacts.**
-
variant.artifacts.get
: SingleArtifact(apk, aab…etc)を取得する -
variant.artifacts.getAll
,variant.artifacts.addStaticDirectory
: MultipleArtifact(debug metadata, symbol tables…etc)を取得、追加する MultipleArtifactはReplaceable, Transformableなartifact -
variant.artifacts.forScope
: Gradle Taskを使って汎用的にScopedArtifactをartifactを操作する -
variant.artifacts.use
: Gradle Taskを使って汎用的にartifactを操作する
-
allProjectsApkAction
- apkファイルを収集するtop levelのタスクを作るサンプル
- Variant.artifactsをタスクのinputに設定しているので暗黙的にタスクの依存関係が構築される(≒トップレベルのタスクを実行するとapkを生成するタスクが実行される)
var taskProvider: TaskProviderAllProjectsApkTask>? = null
taskProvider = project.tasks.registerAllProjectsApkTask>("allProjectsAction") {
outputFile.set(project.layout.buildDirectory.file("list_of_apks.txt"))
}
androidComponents.onVariants(selector().withBuildType("release")) { variant ->
taskProvider?.configure { task ->
task.inputDirectories.add(
variant.artifacts.get(SingleArtifact.APK)
)
}
}
appendToMultipleArtifact
- addMultipleArtifactと同じようなことをするがこちらは自動生成ファイルを追加する
-
com.android.build.api.artifact.Artifacts#use
を使うと設定したタスクがMultipleArtifact.NATIVE_DEBUG_METADATA
を収集するタスクの依存関係に組み込まれる
variant.artifacts.use(generateNativeDebugMetadataTask)
.wiredWith(GenerateNativeDebugMetadataTask::output)
.toAppendTo(MultipleArtifact.NATIVE_DEBUG_METADATA)
appendToScopedArtifacts
- ScopedArtifactsを追加する
-
ScopedArtifacts.Scope
-
ALL
: インポートされたプロジェクト、外部依存込み -
PROJECT
: プロジェクトのみ
-
-
ScopedArtifact
-
CLASSES
: classファイル、Jacocoを除くASMの結果も含む -
JAVA_RES
: 所謂普通のjavaプログラムにおけるresouceファイル e.g.)kotlin-tooling-metadata.json
-
applyFusedLibraryPlugin
- 複数のartifactを単一のaarにまとめる
-
gradle.properties
にandroid.experimental.fusedLibrarySupport=true
を追加することで、AGPがFusedLibraryPluginを適用する - FusedLibraryPluginはAGP8.5以降、Android Developerからは消えているっぽい
- AOSPにはまだ実装が存在しているので表にでないだけでAGP8.5以降も使用可能
-
dependencies
句にinclude
を追加することでaarに含める内容をコントロールするが、aar or jar以外はコンパイル済みのclassファイルが梱包される(イメージとしてはstatic library)- fused libraryをpublishした際の
pom.xml
を見る限り内部で使用しているライブラリの依存が表示されない
- fused libraryをpublishした際の
asmTransformClasses
-
compile後にASMを使ってclassファイルを変換するサンプル
-
instrumentation#setAsmFramesComputationMode
でASMのスタックフレームと最大スタックサイズの扱いを指定する-
FramesComputationMode.COMPUTE_FRAMES_FOR_ALL_CLASSES
: オリジナルをスキップして計算もしない -
FramesComputationMode.COMPUTE_FRAMES_FOR_INSTRUMENTED_CLASSES
: オリジナルをスキップしてゼロから計算する -
FramesComputationMode.COMPUTE_FRAMES_FOR_INSTRUMENTED_METHODS
: 変更もしくは追加されたメソッドを計算する -
FramesComputationMode.COPY_FRAMES
: オリジナルをそのまま使用する
-
-
始めはTraceClassVisitorを使いながら実装するとよい
TraceClassVisitorのoutput
// class version 61.0 (61)
// access flags 0x31
public final class com/example/android/recipes/sample/SomeSource {
// compiled from: SomeSource.kt
@Lkotlin/Metadata;(mv={1, 9, 0}, k=1, xi=48, d1={"u0000u0012nu0002u0018u0002nu0002u0010u0000nu0002u0008u0002nu0002u0010u000enu0000u0018u00002u00020u0001Bu0005u00a2u0006u0002u0010u0002Ju0008u0010u0003u001au00020u0004Hu0002u00a8u0006u0005"}, d2={"Lcom/example/android/recipes/sample/SomeSource;", "", "()V", "someMethod", "", "app_debug"})
// access flags 0x1
public ()V
L0
LINENUMBER 18 L0
ALOAD 0
INVOKESPECIAL java/lang/Object. ()V
RETURN
L1
LOCALVARIABLE this Lcom/example/android/recipes/sample/SomeSource; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
// access flags 0x12
private final someMethod()Ljava/lang/String;
L0
LINENUMBER 20 L0
LDC "something"
ARETURN
L1
LOCALVARIABLE this Lcom/example/android/recipes/sample/SomeSource; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
}
createSingleArtifact
- AndroidComponentsExtensionを使ってビルド時に
AndroidManifest.xml
を生成するサンプル - サンプルでは丸っと新規で
AndroidManifest.xml
を生成している(toCreate)が、単に記載をちょっと変える(toTransform)こともできる
androidComponents.onVariants { variant ->
// create new manifest
variant.artifacts.use(produceManifestTask)
.wiredWith(ProduceAndroidManifestTask::outputManifest)
.toCreate(SingleArtifact.MERGED_MANIFEST)
// modify existing manifest
variant.artifacts.use(produceManifestTask)
.wiredWithFiles(
ProduceAndroidManifestTask::mergedManifest,
ProduceAndroidManifestTask::outputManifest
)
.toTransform(SingleArtifact.MERGED_MANIFEST)
}
disableTests
-
AndroidComponentsExtension#beforeVariants
を使って、test
やandroidTest
を無効化するサンプル -
テストコードがないモジュールなどそもそもテストする気がないvariantやmoduleに対して使うと有効
- そもそもKotlin Compileなどが実行されなくなる
- androidTestにコードがない場合に
./gradlew connectedAndroidTest
を実行するとハングしたりすることが稀にある
-
HostTestBuilder(unit test, screenshot test), HasDeviceTests(instrumented test)それぞれを柔軟に有効・無効化できる
extendingAgp
-
AndroidComponentsExtension#registerExtension
を使ってbuild type、product flavorを慮った独自Extensionを作成するサンプル - サンプルではVerifierTaskで独自Extensionの値を参照しているだけだが、実際には独自Extensionの値を使ってAndroidManifestやresourceをごにょったっていい
getMultipleArtifact
getScopedArtifacts
getSingleArtifact
legacyTaskBridging
- 通常のGradle TaskをAndroidComponentsExtensionに組み込むサンプル
- Copyタスクそのままだと依存を組み込めないのでサブクラスを作成して組み込んでいる
listenToArtifacts
- artifactを生成するTaskを改変せずにartifactを取得するサンプル
- toListenTo: artifactを生成するTaskをHookする
- artifactのパスをそのままTaskに渡さず、BuiltArtifactsLoaderをTaskに渡して取得する部分は通常のGradle Taskとは違う点になる
// 👇みたいに自前でTaskのoutputに対して依存を構築しなくてよい
def assembleTask = project.tasks.named("assembleDebug")
tasks.register("printArtifact") {
doLast {
println assembleTask.get().outputs.files.singleFile
}
}
listenToMultipleArtifact
onVariants
perVariantManifestPlaceholder
- onVariantsと似たような話
-
AndroidComponentsExtension#onVariants
を使って、variantごとにmanifest placeholderを変更するサンプル - 詳細はmanage-manifests
-
app/build.gradle
にごちゃごちゃ書くより、プラグインとして別出しした方が管理しやすくなるかもしれない
registerPreBuild
-
variant.lifecycleTasks.registerPreBuild
を使うと任意のタスクをbuildの前に実行することができる - AGP8.10には
variant.lifecycleTasks.registerPreInstallation
が追加されている- 任意のタスクをアプリをインストールする前に実行することができる(たぶん)
selectVariants
- variant filterはdeprecatedになったので、
AndroidComponentsExtension#beforeVariants
を使ってねというサンプル - build-variants#filter-variantsにも同じ話が書かれている
testFixtures
- testFixturesを有効化するサンプル
- HasTestFixturesBuilderを使ってvariantごとに有効無効も切り替えられる
- AGP自体は
android.experimental.enableTestFixturesKotlinSupport=true
を設定することでKotlinをTestFixturesで使用することができるがKotlinとGradleの問題でGradle Hostedなテストではまだ動作しない
transformAllClasses
- asmTransformClassesとは別アプローチでclassファイルを変換するサンプル
- ASMを使用せずにjarファイルからclassファイルを読み取り、Javassistを使ってclassファイルを変換している
transformDirectory
- createSingleArtifactと似たような話
-
toTransform
を使って、assetの中身をビルド時に変換するサンプル
transformManifest
- createSingleArtifactと似たような話
-
toTransform
を使って、AndroidManifest.xmlをビルド時に変換するサンプル
transformMultiple
variantDependencySubstitutionTest
variantOutput
workerEnabledTransformation
-
ArtifactTransformationRequest#submit
を使うとGradle Worker APIを使用できるよというサンプル - 通常、Gradle Workerを使う場合はinjectしたWorkerExecutorを使用してWorkQueueを取得し、Taskをsubmitするがその辺りがAGP側に委譲する必要があるので注意が必要
- 似たような形でGradle Build Servicesを使うこともできる(はず)