#DroidKaigi 2019で「今日から始める依存性の注入」という発表をしました
DroidKaigi 2019
今年もやってきました。
#DroidKaigi きたよー pic.twitter.com/AqW6mOmG8H
— kobakei (@kobakei122) 2019年2月7日
参加は4回目、登壇は2年連続2回目になります。
ちなみに去年の登壇レポートはこちらです。
続きを読むAndroidプロジェクトでSpek 2.0 RC1を動かす
色々なものに複雑に依存しているので整理してみました。
依存関係
Spek本体
- Spek
- まずは当然これ
Spek2が必要とするもの
android junit5が必要とするもの
- JUnit5
- Android Gradle Plugin 3.2.0以上
- 最新のAndroid Studioなら基本大丈夫
- Gradle 4.7
- 最新のAndroid Studioでプロジェクトを作成するとデフォルトではGradle 4.6を使っているので注意
手順
1. Gradleのバージョンアップ
gradle/wrapper/gradle-wrapper.properties を開き、distributionUrlのバージョン番号を更新。本記事執筆時の最新は4.10.2なので4.10.2と書き換える。
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
Gradle Syncしてダウンロードする。一応この状態でビルドが通るか確認する。
2. android-junit5 & JUnit5の追加
android-junit5のREADMEに従ってbuild.gradleを編集していく。
- ルートのbuild.gradleのビルドスクリプトに追加
buildscript {
dependencies {
classpath "de.mannodermaus.gradle.plugins:android-junit5:1.3.1.1"
}
}
- モジュールのbuild.gradleの一番上にapply plugin、dependenciesにJUnit5を追加する(JUnit4の依存は消す)
apply plugin: "de.mannodermaus.android-junit5"
dependencies {
testImplementation "org.junit.jupiter:junit-jupiter-api:5.3.1"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.3.1"
}
JUnit4で書かれたテストがあったらテストは失敗するかもしれないが、ビルドが通るか再度確認しておく。
3. Spekの追加
Android用のセットアップガイドがあるので、これに従って再びモジュールのbuild.gradleを編集していく。
- テストエンジンの指定
android {
...
testOptions {
junitPlatform {
filters {
engines {
include 'spek2'
}
}
}
}
}
- 依存関係の追加
dependencies {
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
// spek
testImplementation "org.spekframework.spek2:spek-dsl-jvm:$spek_version"
testImplementation "org.spekframework.spek2:spek-runner-junit5:$spek_version"
// spek requires kotlin-reflect, omit when already in classpath
testImplementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
}
これで終わり。Gradle Syncしておく。
4 テストを書く
あとはテストを書いていくだけ。
import org.spekframework.spek2.Spek import org.spekframework.spek2.style.specification.describe object MyAndroidSpekTest : Spek({ describe("a") { context("b") { it("c") { ... } } } })
おまけ: Androidフレームワークに依存しないモジュールの場合
SpekのJVM用ガイドに従うだけでよい。android-junit5の手順は不要。
apply plugin: 'kotlin'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
//implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
// junit5
testImplementation "org.junit.jupiter:junit-jupiter-api:5.3.1"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.3.1"
// spek2
testImplementation('org.spekframework.spek2:spek-dsl-jvm:2.0.0-rc.1') {
exclude group: 'org.jetbrains.kotlin'
}
testRuntimeOnly('org.spekframework.spek2:spek-runner-junit5:2.0.0-rc.1') {
exclude group: 'org.junit.platform'
exclude group: 'org.jetbrains.kotlin'
}
testRuntimeOnly "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
}
test {
useJUnitPlatform {
includeEngines 'spek2'
}
}
#iOSDC に採択されました
表題の通りです。
去年の年末に社内のiOSリソース不足が理由で、AndroidエンジニアからiOSエンジニアに転向しました。「iOSやるからにはでかいカンファレンスで喋れるくらいのレベルになるぞ」という目標を密かに掲げてたんですが、これで一応達成見込みが立ちました。
続きを読む半年ほど副業をやってみた
ここ半年ほど副業をやってみたので、そこまでの過程とやってみた感想を書いておきます。
続きを読むKingfisherのリクエストヘッダーを書き換える
KingfisherのCheat Sheetより。AnyModifierを使う。
let modifier = AnyModifier { request in var r = request r.setValue("", forHTTPHeaderField: "Access-Token") return r } imageView.kf.setImage(with: url, placeholder: nil, options: [.requestModifier(modifier)])
毎回オプションにAnyModifierを渡すのがめんどくさい場合は、KingfisherManager経由でセットすればよい。
KingfisherManager.shared.defaultOptions.append(.requestModifier(modifier))
BottomSheetDialogFragmentの使い方
あまりまとまってないようなのでメモ。
昔は setupDialog をオーバーライドしていたが、サポートライブラリが @RestrictTo(LIBRARY_GROUP) を付けるようになったので警告が出る。代わりに、 onCreateDialog をオーバーライドして中でビューを作成するのがよさそう。
class MyBottomSheet : BottomSheetDialogFragment() { companion object { // Fragmentと同様、インスタンス生成はstaticメソッドで行う fun newInstance(): MyBottomSheet = MyBottomSheet() } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val dialog = super.onCreateDialog(savedInstanceState) // dialogに、自分で作ったビューをセットする val inflater = LayoutInflater.from(context) val binding: MyBottomSheetBinding = MyBottomSheetBinding.inflate(inflater) dialog.setContentView(binding.root) return dialog } }