kokoakumaのメモ (original) (raw)
概要
組立時の情報を残していなかったので、メモ
2021/10/01購入&組立
- ケース P10 FLUX 9073円
- 電源 Antec NeoEco750GOLD 9091円
- GPU GeForce RTX3060 Ti 67701円
- CPUクーラー SCMG5100 無限五 5037円
- RAM XPG GAMMIX D20 DDR4 Memory 16GBx2 15800円
- マザボ TUF GAMING B560-PLUS WIFI 16245円
- CPU Intel i7-11700 35346円
- DVD GSH24NSD5BLBLH 日立LGデータストレージ 1980円
- HDD ST2000DM005 SEAGATE BARRACUDA 2TB 5346円
- SSD MZV8V1TOBIT SAMSUMG SSD 980 MVMe M.2 11800円
メモ
ちょうどグラボが高騰してた。WIFIが機能せず、USBに挿すタイプで代用した。
KSP2における変更
android-developers.googleblog.com
上のAndroid Developersのブログ記事にて様々な変更点が紹介されています。その中でも特にスタンドアローンに実行できる点が気になったため試してみました。
エントリーポイントのあるライブラリとして実装されているため、デバッグやテストが容易になっているらしいです。
テストを書いてみる
試しにコード生成の単体テストを書いてみます。
依存関係を追加する
まずは依存関係を追加します。
implementation("com.google.devtools.ksp:symbol-processing-aa-embeddable:")
// もし足りない場合は以下の依存関係も追加する implementation("com.google.devtools.ksp:symbol-processing-api:") implementation("com.google.devtools.ksp:symbol-processing-common-deps:")
実行したいモジュールに任意のバージョンのsymbol-processing-aa-embeddableを追加します(執筆時点の最新は2.0.0-RC2-1.0.20)。 筆者の手元の環境では、KSPLoggerとKSPJvmConfigの情報が足りなかったため、symbol-processing-apiとsymbol-processing-common-depsも追加しています。
テストを書く
Processorを書いている前提で簡単なテストコードを書いてみます。
以下が最終的なテストコードです。
class SampleTest { // 生成ファイル用のDirの生成 @JvmField @Rule val kotlinOutputDirFolder = TemporaryFolder() // その他のファイル用のDir生成 @JvmField @Rule val dummyFolder = TemporaryFolder()
@Test
fun sample_test() {
// 生成ファイル用のFileインスタンス生成
val annotationFolder = kotlinOutputDirFolder.newFolder(
"com", "sample", "annotation"
)
val generatedFile = File(annotationFolder, "GeneratedFile.kt")
// Processorが処理するファイルの準備
val projectFile = File(dummyFolder.root, "Project.kt")
projectFile.writeText(
"""
package com.sample.ksp
@TargetAnnotation
Interface Hoge
annotation class TargetAnnotation()
""".trimIndent(),
)
// Configの生成
val kspConfig = KSPJvmConfig.Builder().apply {
kotlinOutputDir = kotlinOutputDirFolder.root
javaOutputDir = dummyFolder.newFolder("java")
outputBaseDir = dummyFolder.newFolder("base")
resourceOutputDir = dummyFolder.newFolder("resource")
cachesDir = dummyFolder.newFolder("cache")
classOutputDir = dummyFolder.newFolder("class")
jvmTarget = JvmTarget.DEFAULT.description
moduleName = "<module_name>"
sourceRoots = listOf(projectFile)
javaSourceRoots = listOf()
commonSourceRoots = listOf()
projectBaseDir = dummyFolder.root
languageVersion = "<version>"
apiVersion = "<version>"
}.build()
val exitCode = KotlinSymbolProcessing(
kspConfig,
listOf(HogeProcessorProvider()),
TestKSPLogger()
).execute()
assertTrue(
exitCode == KotlinSymbolProcessing.ExitCode.OK
&& generatedFile.exists()
)
}
}
class TestKSPLogger: KSPLogger { override fun error(message: String, symbol: KSNode?) { // operation } override fun exception(e: Throwable) { // operation } override fun info(message: String, symbol: KSNode?) { // operation } override fun logging(message: String, symbol: KSNode?) { // operation } override fun warn(message: String, symbol: KSNode?) { // operation } }
順番に見ていきます。
フォルダを用意する
Configを作成する際、ファイルの読み込み先と出力先となるディレクトリを渡す必要があるようです。今回はTemporaryFolderを使用してフォルダを生成しました。
@JvmField @Rule val dummyFolder = TemporaryFolder()
テストメソッド毎にフォルダを再作成できるように、Ruleアノテーションを付けておきます。 また、Kotlinで使用する場合はJvmFieldアノテーションも必要みたいです。
読み込むファイルを用意する
SymbolProcessorの処理対象となるファイルを用意します。
val projectFile = File(dummyFolder.root, "Project.kt") projectFile.writeText( """ package com.example.ksp
@TargetAnnotation
Interface Hoge
annotation class TargetAnnotation()
""".trimIndent(),
)
Configを用意する
諸々の設定情報を渡すためにKSPJvmConfigを用意する必要があります。
val kspConfig = KSPJvmConfig.Builder().apply { kotlinOutputDir = kotlinOutputDirFolder.root javaOutputDir = dummyFolder.newFolder("java") outputBaseDir = dummyFolder.newFolder("base") resourceOutputDir = dummyFolder.newFolder("resource") cachesDir = dummyFolder.newFolder("cache") classOutputDir = dummyFolder.newFolder("class") jvmTarget = JvmTarget.DEFAULT.description moduleName = "" sourceRoots = listOf(projectFile) javaSourceRoots = listOf() commonSourceRoots = listOf() projectBaseDir = dummyFolder.root languageVersion = "" apiVersion = "" }.build()
先ほど作成した出力先のフォルダをkotlinOutputDirに、読み込むファイルをsourceRootsに設定します。残りはよしなに埋めておきます。
Loggerを用意する
KotlinSymbolProcessingにKSPLoggerを実装したクラスを渡す必要があります。
class TestKSPLogger: KSPLogger { override fun error(message: String, symbol: KSNode?) { // operation } override fun exception(e: Throwable) { // operation } override fun info(message: String, symbol: KSNode?) { // operation } override fun logging(message: String, symbol: KSNode?) { // operation } override fun warn(message: String, symbol: KSNode?) { // operation } }
KSPの処理を実行する
作成しておいたConfigとSymbolProcessorProvider、Loggerを渡して、executeメソッドを呼びます。今回は、返り値のExitCodeと生成ファイルを用いてassertしておきます。
val exitCode = KotlinSymbolProcessing( kspConfig, listOf(HogeProcessorProvider()), TestKSPLogger() ).execute() assertTrue( exitCode == KotlinSymbolProcessing.ExitCode.OK && generatedFile.exists() )
参考リンク
Is there any guidance or example project for how to use KSP2 kotlinlang #ksp
Prepare for K2 by ZacSweers · Pull Request #196 · ZacSweers/kotlin-compile-testing · GitHub
概要
https://developer.android.com/design-for-safety/privacy-sandbox/introduction
ユーザープライバシー保護を目的としていて、主に以下二つの解決策が盛り込まれているものです。 (あくまでプロポーザルの段階)
SDK Runtime
https://developer.android.com/design-for-safety/privacy-sandbox/sdk-runtime SDK Runtimeは、サードパーティのSDKを専用のランタイム環境で実行できるようにするもの (アプリのサンドボックス環境と似たもの) アプリはSDKのインタフェースを介して、SDKランタイム内のSDKにアクセスするらしいです。 このSDKとの分離はSDKの配布方法とも関連していて、以下のようなメカニズムが紹介されていました。
プライバシー保護API
プライバシー保護APIは、アプリ間の識別子に依存せずに広告のパーソナライズと測定をサポートするもの
- Topic
- Protected Audience
- Attribution Report
Topic
ユーザーの過去のアプリ使用内容に基づいて大まかな広告のトピックを推測するもの これによって、個々のユーザーをアプリ間で追跡することなく、興味・関心に基づく広告(IBA)のユースケースをサポートできるらしいです。
Protected Audience
(よくわからない)
Attribution Report
広告IDのようなクロスパーティなユーザー ID への依存を排除することでユーザーのプライバシーを向上しつつ、アプリとウェブ全体でのアトリビューションとコンバージョン測定の主要なユースケースをサポートできるらしいです。
影響ありそうなサードパーティ
インストールと遷移元の広告の紐付け
例)Adjust、AppFlyer
紐づける際の根拠として広告IDを使用しているため、影響を受ける可能性大です。https://help.adjust.com/ja/article/attribution-methodsAdjustは既にブログを出しており、該当部分の内容は以下のようになっていました。
- 従来のアトリビューション(紐付け)において、インストールリファラーに基づく方法は使用できるはず(今のところ廃止の発表がないため)
- Privacy sandboxが標準となった後の話はリダイレクトなしのアトリビューションという項目を確認してほしい
https://www.adjust.com/ja/blog/what-google-privacy-sandbox-for-android-s-beta-launch-means-for-app-marketers/ https://www.adjust.com/ja/blog/privacy-sandbox-on-android-mobile-attribution/ https://developer.android.com/design-for-safety/privacy-sandbox/attribution?hl=ja#cross-network-attrib-without-redirects
Firebase
デフォルトだと広告IDを取得しているようですが、どう影響するかは追えていないです。https://firebase.google.com/docs/analytics/configure-data-collection?hl=ja&platform=android#disable_advertising_id_collection
iOSのAnalyticsWithoutAdIdSupportの質問↓https://stackoverflow.com/questions/70166513/what-are-the-downsides-of-using-firebase-analytics-without-ad-id-analyticswitho
マーケ運用ツール
例)KARTE
KARTEでは広告IDを渡すメソッドが用意されているため、広告IDに基づいた分類や連携を行なっているか確認していただくと良さそうです。https://support.karte.io/post/13v6pgNyNKtrxyIvYZcnAs
広告
Topicやattributionについて、案内が出始めています。https://developers.google.com/admob/android/privacy/sandbox https://developer.android.com/design-for-safety/privacy-sandbox/attribution#extended-debugging-reports
初見では分かりづらいエラーだったため、備忘録として残しています。
error while writing ...$1.class (Permission denied...)と怒られた
Androidのテストケース名を日本語で書いていた時、ローカルでは問題なく通るものの、GitHub ActionsのCI上でerror while writing ...$1.class (Permission denied...)と怒られてしまいました。
他の日本語で書かれているテストは問題なく成功しているのに、これだけ落ちるのはどういうことなんだ、、、と途方に暮れていましたが、メンバーの方から「文字数が多いとそのエラーが出るよ」と教えてもらいました。
実際にテストケース名を短くしてみたところ、上記エラーは出なくなりました(初見で絶対分からん)。
ただ、これで終わりにするのも気持ち悪いのでもう少し調べておきます。
エラーの発生原因
このページのコメント欄を見ると、Linuxのファイル名が最大255bytesまでであり、ファイル名またはファイル名 + パスがその上限に引っかかっているのではないかというやりとりがされています。
実際に自分が最初に書いたケース名を確認してみると、
HogeTest$$1.class
で260bytesとなっており、上記の話に当てはまりそうでした。
ライブラリが提供しているモジュールをインジェクトする時と同様に、 provideメソッドを書いてあげれば大丈夫。
@Module @InstallIn(SingletonComponent::class) class RepositoryModule {
@Provides @Singleton fun provideHogeRepository( httpClient: HttpClient, @IODispatcher dispatcher: CoroutineDispatcher ): HogeRepository { return HogeRepositoryImpl( httpClient, dispatcher ) } }
interface HogeRepository //
class HogeRepositoryImpl //