[Android] [Kotlin] Android開発でRoomとKoinの設定

今、UdemyのAndroid開発コースをやっていて、そのコースではRoomとToothPickというライブラリを使って開発が進むのですが、個人的にKoinを使いたくてドキュメント見ながらやると見事に設定の記述漏れでハマったので、備忘録として書いておきます。

Kotlinのバージョンは、1.3.20 を使用。

Module: appbuild.gradle に以下の記述を追加する。

// Room
def room_version = "2.1.0-alpha05"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"

// Koin
def koin_version = "1.0.2"
implementation "org.koin:koin-android:$koin_version"
implementation "org.koin:koin-android-scope:$koin_version"
implementation "org.koin:koin-android-viewmodel:$koin_version"

今回、以下の設定が抜けていたためビルドは通る?けど、アプリが起動しないため原因が最初どこかわからなくて1時間ぐらい時間溶かしてしまいました。

// Room
kapt "androidx.room:room-compiler:$room_version"

ちなみに、kapt を利用するには以下の記述が必要です。

apply plugin: 'kotlin-kapt'

kaptは Kotlin Annotation Processing Tool(であってる?)で、 Java6から導入された Pluggable Annotation Processing API を Kotlinからも利用できるようにしたものです。

Koinは Applicationクラスを継承したAppクラスに設定を記述しました。

class App : Application() {
    override fun onCreate() {
        super.onCreate()

        startKoin(this,
            listOf(AppModule.module())
        )
    }

    companion object {
        lateinit var instance: Application
    }

    init {
        instance = this
    }
}

AppModulemodule() 関数内にDIの設定を記述しました。

object AppModule {
    fun module() = module {
        single<ITaskModel> { TaskLocalModel() }
        single<INoteModel> { NoteLocalModel() }
        single {
            RoomDatabaseClient.getInstance(App.instance.applicationContext)
        }
    }
}

これで合っているのかよく分からないので、間違っていたらコメントとかもらえると嬉しいです。

以上です。

UdemyのKotlin for Android O Developmentというコースが良かった!

普段はWeb開発しかしていないのだけれど、モバイルアプリを開発する必要性が出てきたので最近いろいろサンプルアプリを作ったり、ライブラリを試しに動かしたりしている。

そのいった中で、Udemyの「Kotlin for Android O Development」というコースが個人的に総合して良いと思ったので、良かった点・気になった点に分けて感想をまとめてみる。

良かった点

Kotlinを使ったAndroidの開発コースであること

このコースはKotlinを使って1からサンプルアプリを開発していくため、KotlinでAndroidアプリを開発していきたいと思っていた僕にはちょうどよかった。

Kotlinで書かれた書籍はいつくかあるもののまだまだJavaで説明されているものも多いので、Udemyのような動画で学ぶことには意味がある。

サンプル数が多い

なにか新しい言語や仕組みを学ぶときは本を読むのも良いが、実際にものを作って動かしてから書籍を読んだ方が個人的には理解力が高まると思っているので、とにかくサンプルアプリを作りまくりたかった。

このコースでは、10個以上のサンプルアプリを作ることが可能なので、とりあえず手を動かして覚えたい人におすすめしたい。

DBを使ったサンプルがある

モバイルアプリを開発するにあたってDBを使うことは多々あるのではないかと思う。

このコースでは簡単ではあるがSQLiteを使ってアプリを作ることもできるので良かった。

Firebaseを使ったアプリも作れる

コースの総まとめとして、今まで作ってきたサンプルアプリの機能を駆使して、そしてFirebaseも利用してアプリを作ることができる。

実際に使ってみると分かるが、Firebase簡単すぎっ!!ってなる。

少し気になったのは、コースで使っているFirebaseのライブラリのバージョンが古いので、 deprecated になっているメソッドを呼び出していたりしていた。

僕がアプリを作ったときは最新バージョンを使うようにしていたので、値がうまく取れないなと思ったら上記のような理由が原因だった。Firebaseドキュメントや他の方の記事を参考にすれば解決できるはずだ。

Android でファイルをアップロードする  |  Firebase

気になった点

ListViewのみを使っていた

おそらくBeginner向けのコースであるからだと思うが、RecyclerViewもコースに盛り込めばいいのにと思った。 おそらく普段Androidアプリを開発されている方はListViewとか使うのか?と思ったりしたのでここらへんは気になった。

Fragmentは扱われていない

普通はAcitivityのみを使って開発は行わないと思うのでFragmentについてのチャプターもあってもいいんじゃないかと思った。 このコースではFragmentは学べないため、記事を見るなり本を読むなりして学ぶのが良いだろう。

最後に

Kotlin for Android O Development: From Beginner to Advanced

このコースは講師の方が英語で説明するため、英語字幕を出しながら動画を視聴していた。話すスピードはゆっくりで難しいことは話さないので、そんなに英語が得意でない僕でも理解できたのでおすすめである。

RecyclerViewやCardViewはAndroid Developersの記事を読むのが良さげ。

developer.android.com

まだまだ知らないといけない部分があるので、このまま継続してAndroid開発の学習・開発を進めていく。

おすすめの記事やこれだけはやっておけみたいなのがあれば、 ブログのコメントかTwitterに投げつけてくださると嬉しいです!

では!

AWS CloudFrontのキャッシュを削除する方法

静的ページをCloudFront + S3でホストしていて画像を更新したけど、キャッシュのせいで反映されないということがありそうです。

そんなときにキャッシュの有効期限まで待つのではなく、自分でキャッシュを削除して反映させたいはず。

この記事では、AWSのCloudFrontでどうやってキャッシュを削除するかを知ることができます。

では、いってみましょう。

ファイルを無効化

CloudFrontにはInvalidationというものがあり、これをCreateすることでキャッシュを削除することができます。 Edgeサーバーにあるファイルを無効化するからInvalidation。

手順

1. コンソールで [CloudFront Distributes]を開く。

f:id:ryskit:20190209171501j:plain

2. [ディストリビューション] を選択する。

選択したディストリビューションの概要が表示されます。

f:id:ryskit:20190209171840j:plain

3. [Invalidations] タブを選択する。

f:id:ryskit:20190209171915j:plain

4. [Create Invalidation] ボタンをクリックする。

f:id:ryskit:20190209172213j:plain

ボックスの中にキャッシュを削除したいファイルのパスを入力してください。

画像のように記述すると、 /images/xxxx.jpg のキャッシュを削除することになります。

まとめてキャッシュを削除したいときは、 /* のような指定をするとすべてキャッシュを削除できます。

5. [Invalidate] ボタンをクリックする。

選択すると、CloudFrontのEdgeサーバーのキャッシュ削除処理が開始されます。 Status が In Progress の場合はまだ削除処理中で、 Complete になれば完了です。

こちらにAWSの公式ドキュメントがあるので、詳細を知りたい場合は参考にしてみてください。

Databindingを利用したアプリをビルドするとUnresolved reference: BR エラーになった

Androidアプリの開発を始めて、Databindingが便利そうというかMVVMなどのアーキテクチャで実装しようとすると必須?みたいなので、とりあえず簡単なサンプルアプリを実装して、どんなものか簡単に実装を理解しようとした。

アプリを書き終わったのでビルドしようとすると Unresolved reference: BR というエラーに出くわしてしまった。

結論から言うと、

(Module: app) build.gradle に apply plugin: 'kotlin-kapt' の記載を書いたら解決した。

経緯

Googleのドキュメントを見る限り、 (Module: app) build.gradleに、

android {
    ....
    dataBinding {
        enabled = true
    }
}

を書くだけでデータバインディングの準備はOKなのかなと思っていた。

そのため、以下のようにViewHolderクラスで ViewDataBinding に変数をセットするコードを書いてビルドしてみるとエラーになった。

class WeatherViewHolder(val binding: ViewDataBinding) : RecyclerView.ViewHolder(binding.root) {

    fun bind(data: Any) {
        binding.setVariable(BR.data, data) // ここで kotlin compiler にUnresolved reference: BR と表示された
        binding.executePendingBindings()     
    }
}

どうやら、BRクラスファイルの参照解決ができてないということで、 うーんとうなりながらぐぐってみると以下の記事に行き着きました。

medium.com

どうやらこいつが必要らしい。

apply plugin: 'kotlin-kapt'

ということで、build.gradleに記載してビルドしてみるとすんなりエラーなくビルドできました。

いろいろ昔の記事を見ていると、

kapt 'com.android.databinding:compiler:x.x.x'

を書いてる記事とかあるんだけど、これはもう書かなくて良いっぽい。

最後に

不慣れなことをすると、すぐバグ踏んだり躓いたりしやすいから、早く慣れていきたい。 友達とサービス作るときに、キダくんAndroidアプリ開発で参加してよ!って声がいっぱいかかるぐらいにはスキルアップしていくぞ!

Rustをインストールして始めてみる

会社の人から、Rustはすごくいいぞ〜と言われ、O'Reillyから出てるプログラミングRustを読んだりしている。

Rustをインストールしたとき、すごく簡単だったので手順を記しておく。 といっても、以下のコマンド叩くだけ。

curl https://sh.rustup.rs -sSf | sh

すごく簡単なので、すぐにRustを始められるのが良かったと思う。

あとRustをインストールすると、CargoというRustのビルドシステム兼パッケージマネージャが一緒にインストールされるけど、これがいろいろ面倒なことを代わりにやってくれるので、プロジェクトのセットアップに躓くことがなかったのは嬉しい。

案件のどこかで使えるようにしておきたい。

GoLand 2018.2 でDebugを起動できなくなった

Goならわかるシステムプログラミングって本を読んでて、 一章には、fmt.Println("Hello World")をデバッガーを使ってシステムコールの「見る」と書いてあったので、 素直にGoLandでデバッガーを起動すると以下のようなエラーが出た。

could not launch process: debugserver or lldb-server not found: install XCode's command line tools or lldb-server

解決策としては以下のチェックボックスにチェックを入れれば解決するよ!

Preferences > Build, Execution, Deployment > Debuggerを開いて、 Use native backend にチェックを入れてApplyすればOK!

f:id:ryskit:20180820013324j:plain

【Golang】RequestからQueryStringを取得するには

最近Golangでコマンドラインツールを作りたくて、Golangのサンプルコードとかを動かしていろいろ遊びながら覚えているところなのですが、たまたまEchoサーバーのプログラムがあったので試したのですがすごく簡単にかけますね!

そのとき、リクエストからQuery Stringをどう抜き出すんだろと思って試しに書いてみました。

package main

import (
    "net/http"
    "log"
    "fmt"
)

func main() {
    http.HandleFunc("/", handler)
    log.Fatal(http.ListenAndServe("localhost:8000", nil))
}

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "%s %s %s\n", r.Method, r.URL, r.Proto)
    v := r.URL.Query()
    if v == nil {
        return
    }
    for key, vs := range v {
        fmt.Fprintf(w, "%s = %s\n", key, vs[0])
    }
}

r.URL.Query()type Values map[string][]string を受け取ることができるので、rangeでループ回して表示しています。

個別にキーを指定して取得したい場合は以下のようにキーを指定してあげれば取得できるはず

r.URL.Query().Get(キー)

EC2のユーザーデータ内でcloud-initとシェルスクリプトを使いたい

こんにちは。こんばんは。

たまたま、CloudFormationのテンプレートから起動されるEC2のユーザーデータを利用して、インストールしておきたいモジュールがありました。

ユーザーデータには、cloud-initシェルスクリプト で何らかの処理を書くことができるのですが、 テンプレートにはすでにcloud-initの形式で書かれており、シェルスクリプトを書こうとするとエラーとなりユーザーデータで書いた内容は実行されません。

EC2のユーザーデータ内で、cloud-initシェルスクリプト を併用したいけどそんなことができるのかといろいろ調べていくうちに、この記事に行き着きました。

cloud-initでシェルスクリプトとcloud-configを同時に使う

はい、やりたかったことはこれです!!

ってことで、実際に自分でやってみた手順を書いていきたいと思います。

cloud-utils パッケージをインストールする

まず、cloud-utils パッケージをインストールしましょう。

$ sudo yum install cloud-utils

※ 上記は、Amazon Linux AMI 2018.03.0 から作成したEC2内で作業をしています。

cloud-init 形式で書いてファイルを作成

viを立ち上げてファイルを作成します。

$ vi cloud-config.txt

そして、以下の内容をコピペして保存してください。

#cloud-config
packages:
  - sl

runcmd:
  - echo "HELLO Cloud Config"

シェルスクリプトで書いてファイルを作成

viを立ち上げてファイルを作成します。

$ vi shell.txt

そして、以下の内容をコピペして保存してください。

#!/bin/bash -xe

touch /home/ec2-user/create-by-shellscript.txt
echo "HELLO ShellScript" >> /home/ec2-user/create-by-shellscript.txt

write-mime-multipart で MIMEマルチパート形式のファイルを作成

先ほど作成した、cloud-config.txtshellscript.txt を使って、 MIMEマルチパート形式のファイルを作成します。

以下のコマンドを実行してみましょう。

$ write-mime-multipart --output=output.txt cloud-config.txt:text/cloud-config shell.txt:text/x-shellscript

するとカレントディレクトリに、output.txt が作成されていると思います。

ファイルの内容を確認するとこのように記述されています。

Content-Type: multipart/mixed; boundary="===============2433150631494388583=="
MIME-Version: 1.0

--===============2433150631494388583==
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"

#cloud-config
packages:
  - sl

runcmd:
  - echo "HELLO Cloud Config"

--===============2433150631494388583==
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="shell.txt"

#!/bin/bash -xe

touch /home/ec2-user/create-by-shellscript.txt
echo "HELLO ShellScript" >> /home/ec2-user/create-by-shellscript.txt

--===============2433150631494388583==--

このファイルの内容をそのままEC2のユーザーデータにコピペして起動してあげると、 処理が自動で実行されます。

f:id:ryskit:20180516203222p:plain

立ち上げたインスタンスにSSHで入って確認してみましょう!

ユーザーデータの内容が実行されたかどうかは、/var/log/cloud-init-output.txt を見れば確認できます。

$ less /var/log/cloud-init-output.log
:
:
Existing lock /var/run/yum.pid: another copy is running as pid 2597.
Another app is currently holding the yum lock; waiting for it to exit...
  The other application is: yum
    Memory :  38 M RSS (286 MB VSZ)
    Started: Wed May 16 11:30:54 2018 - 00:00 ago
    State  : Running, pid: 2597
Resolving Dependencies
--> Running transaction check
---> Package sl.x86_64 0:5.02-1.6.amzn1 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

================================================================================
 Package     Arch            Version                   Repository          Size
================================================================================
Installing:
 sl          x86_64          5.02-1.6.amzn1            amzn-main           13 k

Transaction Summary
================================================================================
Install  1 Package

Total download size: 13 k
Installed size: 15 k
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : sl-5.02-1.6.amzn1.x86_64                                     1/1
  Verifying  : sl-5.02-1.6.amzn1.x86_64                                     1/1

Installed:
  sl.x86_64 0:5.02-1.6.amzn1

Complete!
Cloud-init v. 0.7.6 running 'modules:final' at Wed, 16 May 2018 11:30:58 +0000. Up 25.17 seconds.
HELLO Cloud Config
+ touch /home/ec2-user/create-by-shellscript.txt
+ echo 'HELLO ShellScript'
Cloud-init v. 0.7.6 finished at Wed, 16 May 2018 11:30:58 +0000. Datasource DataSourceEc2.  Up 25.50 seconds

正しくログが吐かれていますね!!

CloudFormationのEC2インスタンスのユーザーデータでも同じことをしたい場合は、 作成したMIMEマルチパート形式のファイルの内容を同じようにコピペしてあげれば動作します。 ただし、JSON形式だとダブルクオテーションで一文一文を囲ってあげないと動作しないと思うのでそこは注意してくださいね。

では!!