Spica*スマートフォン用の表示で見るSpica*プログラミングの話。Daggerに入門してみました。appを教えてもらいました。Daggerも教えてもらったんですけど、英語を勉強中なのと、公式のリソースだけで進めたい気持ちもあり、どれを読むかを悩んだ結果CodeLabsを選びました。今回はそのときに学んだ内容のメモを書きます。Daggerで使用するAnnotations周りのメモとなります。僕がDaggerを勉強したいなと思ったのは、ユニットテストをやりたかったからです。僕は今DIを使っていないプロジェクトを触っていて「ユニットテストを書きたい」気持ちがわりとあります。してもユニットテストをするために書かなければならないコードが多い、かつmockにしないといけないオブジェクトが多いために、テストが書き始めれない...となっているところです。DIを使うと、クラスをインスタンス化する時に渡す必要のあるインスタンスを必要なものだけにできるので、モックにするものを限定的にすることが可能です。そこに魅力を感じています。Injection(DI)のためのライブラリです。Androidだけでなく、Javaプロジェクトでも利用できます。「Daggerを使用することで、コードの再利用性を高め、リファクタリングやテストを容易にします」とのこと。Androidやその他リソースを読むのがよさそうです。基本的なAnnotations@Inject二種類あります。コンストラクタにつける@InjectDaggerが、どうやってインスタンスを作るかを知るために必要なアノテーション。これをクラスのコンストラクタにつけることで、@Injectをつけたコンストラクタの引数は、そのクラスの依存であることをDaggerが知ることができるこれはDaggerが生成できるインスタンスに限ってつけることが可能。AndroidではActivity/Fragmentなどはシステムが生成する。Dagger自身が生成することはできない。injectionを使用する。injectionでの@InjectAndroidフレームワークは、システムによってActivityやFragmentが生成される。そのため、Daggerによってインスタンスを生成できない。Injectionを使う。LoginViewModelの宣言に、@Injectをつけた。この場合、Daggerは、LoginActivityをDaggerコンポーネントであるAppComponentの#inject()メソッドにLoginActivityを渡すことで、DaggerにLoginViewModelを注入して欲しい事がわかるAppComponent#inject(this)をActivityで呼び出す場合、super.onCreateよりも前に書く必要がある。Fragmentの再生成時の問題を回避するため。Fragmentに書く場合は、onAttach()メソッド内のsuper.onAttachよりも後であること。Storage}@Provides@ProvidesはGitHubBrowserSampleのAppModule.ktを見るのがわかりやすい@BindsInstanceContextのように、Daggerによって生成できないインスタンスもある。このアノテーションを使って、例えばContextをDaggerにインスタンスを渡しておくと、Daggerが何らかのインスタンスを生成する際、インスタンスがContextを要求した場合、渡しておいたContextインスタンスを使ってインスタンスを生成するスコープDaggerでは、@Injectの対象のインスタンスは、毎回Daggerによって生成される。これがデフォルトの動き。毎回newするのではなく、同じインスタンスを複数の画面で使いまわしたい場合がある。この場合に使うのがスコープ。...}@SubcomponentActivity単位でインスタンスを持たせたい、といった場合に使用するのがDaggerサブコンポーネントサブコンポーネントは親コンポーネント(今回でいうとAppComponent)を継承している。親コンポーネントで用意されたオブジェクトは、子コンポーネントでも用意されている状態である。@ActivityScopeこれをComponent(@Subcomponent)につけた場合、そのコンポーネント毎にインスタンスをユニークにもてる作成したスコープアノテーションは使い回すことができる。そのため、作成するアノテーションは機能単位(ドメイン単位?)でないほうがよい所感DaggerのDocumentationを読んでて思ったのは、「なんか便利そうだから入れてみる」みたいなノリで入れると、「DI使うのかい?使わないのかい?どっちなんだい?」って感じになって地獄を見るかもしれないので、基礎を勉強した上で(チームでの開発をしている場合はチームを説得するなりして)入れるのがよいかなって思っています。あと、もし既存プロジェクトにDaggerを導入する場合は、まずはリファクタリングから始めなければならないかも知れません。graph(アプリで使用しているクラスの依存関係)を考え確立したうえで、導入した方がよさそうです。Daggerは情報量が多く、ドキュメントが色んな所に散らばっている上に、古い情報も残っていたりして、かなりいろいろなところを読まないといけない状態になっています。これは学習コストをさらに引き上げている一つの要因のような気がします...。おまけ:dagger-androidについてDaggerをAndroidプロジェクトに導入するには、下記をbuild.gradleに入力すればOKです。"com.google.dagger:dagger-compiler:2.24"}これはCodeLabsのapp/build.gradleを見ると分かります。僕は終わってから気づいたんですが、CodeLabsの内容は、Daggerの基本のみです...。このままでもプロジェクトへの導入は可能ですが、もっと効率的にAndroidのプロジェクトでDaggerを使うには、dagger.dev/androidにある、dagger-androidやdagger-android-supportといったライブラリの使い方も覚えたほうが良いです。GitHubBrowserSampleには、実際にこれらのライブラリを使ったサンプルがあります(基礎がわかってないとソースみてもちんぷんかんぷんです)。dagger-androidを含めたDaggerライブラリ全体を入れるには、下記のコードをbuild.gradleに入れる必要があります。"com.google.dagger:dagger-android-processor:2.24"}↑のようなdaggerの基本ライブラリからdagger-android-supportまでを含めたすべてのdependenciesの導入方法は、GitHubBrowserSampleの中身を見て調べました。公式に書いてそうなんですが、僕自身がその導入方法を書いてるところを見つけれていません。it?セクションは古いし...。23:53Daggerに入門したTweet広告を非表示にするもっと読むコメントを書く2019-10-13Catalinaへアップグレードした会社のPCをアップデートする前に、自分のPCをCatalinaにアップグレードしといた。インストールダウンロードで20分程度、インストールは1時間程度だった酷使しているPCではないので、よく使っているPCとかだともっと時間かかるのかも気になったことCatalinaインストール後、通知を許可するかどうかのNotificationが沢山表示された。ドライブディレクトリを選択すると、通常通り使えるようになったMac付属の辞書アプリ(dictionary.app)を開くと「辞書が構成されていません」という状態になっていたしかし、辞書を構成する画面を開くと、以前選択していた辞書にチェックは入っていたXcodeをインストールするために容量を開けるのが大変だったストレージ自体は23.01GB空いていたが、それでも足りないと言われた所管アップデートして少し使ってみたけど、大きな問題は起きてないSteamを手動でアップデートしなければならなかったくらい。あと、一つだけゲーム入れてたんだけど、32-bitのみ対応だったので動かなくなった...古いゲームなので仕方がない。今後64-bit対応されることもないだろう...Xcodeは現在インストール中3-4時間くらいかかってる気がする...Catalinaのアップグレードよりも時間がかかってるSidecarはiPad持ってないので試してない。iPadが欲しくなってきた。これはインパクトでかいのでは。Catalystがすげー気になる。