LoginSignup
2
5

More than 5 years have passed since last update.

Android開発まとめ 個人メモ

Last updated at Posted at 2017-12-11

概要

数年ぶり(2017年12月現在)にAndroid開発をすることになりました。
当時はEclipseの時代でしたが、色々変わってることが多々あり、
現状のベストプラクティスを模索しています。
今後自分がAndroidの開発をしていく上で調査した内容などを個人的な見解でまとめます。

注意

個人メモのため記事は都度成長していきます。
分割して別の記事になる可能性もあります。

開発環境

  • Android Studio 3.0
  • Kotlin 1.2
  • MacOS 10.12

Android Studio

よく使う設定

Android Studioのテーマの変更

http://color-themes.com/?view=index
で好きなテーマをダウンロードする。
Obsidianかな。
http://color-themes.com/?view=theme&id=563a1a6180b4acf11273ae3d
テーマ名前.jarが落ちてくるので
File -> import settigns からjarをインポート。再起動を求められるので再起動する。

Android Studioで使用していないImportを自動削除する

http://tatuas.hatenablog.com/entry/2015/05/26/135640
Settingを開き、Editor > General > Auto Importで、Javaカテゴリの「Optimize imports on the fly」チェックボックスをつける。

Parcelableを自動生成する

※ParcelableはBundelに設定できるオブジェクト。

Preferences > Plugin > Brouse repositories...ボタン
[parcelable]で検索
Android Parcelable code generatorをインストール
※kotlinの場合は for kotlinをインストール

dataクラスで コマンド+N でgenerateを表示し parcelableで生成できる。

ライブラリの利用 Gradle

build.gradleはProject配下とapp配下がある。
どちらに配置するべきか要検討

今後要調査

dependenciesにおける
* classpath
* compile
* impementation
の違い

dependenciesのkaptを指定する意味

HTTPクライアント

Retrofit2 + GSON

Retrofit2公式
http://square.github.io/retrofit/

GSONのgithub
https://github.com/google/gson

build.gradle
dependencies {
    compile 'com.squareup.retrofit2:retrofit:2.3.0'
    compile 'com.squareup.retrofit2:converter-gson:2.3.0'
    compile 'com.google.code.gson:gson:2.8.2'
}

MVVM

Rx+DataBinding

  • RxJava
  • RxKotlin
  • DataBinding
  • RxProperty
build.gradle
dependencies {
    implementation 'io.reactivex.rxjava2:rxjava:2.1.7'
    implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
    implementation 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
    implementation 'com.jakewharton.rxbinding2:rxbinding-kotlin:2.0.0'
    implementation 'me.tatarka.bindingcollectionadapter2:bindingcollectionadapter:2.2.0'
    implementation 'me.tatarka.bindingcollectionadapter2:bindingcollectionadapter-recyclerview:2.2.0'
    kapt "com.android.databinding:compiler:$android_plugin_version"
    compile 'com.github.k-kagurazaka.rx-property-android:rx-property:4.0.0'
    // If you want to use Kotlin syntax
    compile 'com.github.k-kagurazaka.rx-property-android:rx-property-kotlin:4.0.0'
}

DB

RealmJava (Database)

build.gradle(Project)
apply plugin: 'realm-android'
dependencies {
    classpath 'io.realm:realm-gradle-plugin:4.3.1'
}
build.gradle(app)
apply plugin: 'realm-android'

よく使う実装

ボタンクリック RxCommand + Api実行のObservable連携

例 LoginAPIを実行するログインボタンのObservableストリーム実装

WebApiの呼び出し Retrofit2 + Gson + Rx

ApiService.kt
interface ApiService {
    @Headers("Accept: application/json", "Content-type: application/json")
    @POST("/api/auth/login")
    fun postAuthLogin(@Body body: Map<String,String>): Observable<LoginData>
}

class ApiInvoker {
    fun login(loginId: String):Observable<LoginData> {
        val map = mapOf("loginId" to loginId)
        val retrofit =  buildRetrofit()
        return retrofit.create(ApiService::class.java)
                .postAuthLogin(map)
                .delay(1, TimeUnit.SECONDS)
                .threadManage()
    }

    private fun <T> Observable<T>.threadManage():Observable<T> {
        return this.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
    }

    private fun buildRetrofit(): Retrofit {
        return Retrofit.Builder()                .client(OkHttpClient.Builder().build())
                .baseUrl("http://192.168.0.2")
                .addConverterFactory(GsonConverterFactory.create(Gson()))
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build()
    }
}

ApiServiceにおけるPOINT

  • HTTPメソッド指定
  • URL指定
  • リクエストヘッダー指定
  • リクエストパラメータ指定
  • レスポンスの型をObservableにする。ジェネリックタイプはレスポンスJSONを表す型

ApiInvokerにおけるPOINT

  • RetffitのBuilderの使い方( buildRetrofit()に閉じ込める)
  • subscribeOnでioスレッドを指定(newThread() でもよい)しバックグラウンド実行
  • observableOnでメインスレッドに戻す。

ViewとViewModelの連携

layout/activity_login.xml
<!-- 肝心なところだけ抜粋 -->
<layout xmlns:app="http://schemas.android.com/apk/res-auto" >
    <data>
        <variable name="vm" type="ViewModels.LoginViewModel" />
    </data>
    <Button android:id="@+id/loginButton"
        ....
        rxCommandOnClick="@{vm.signinCommand}" />
</layout>

LoginActivity.kt
var viewModel: LoginViewModel = LoginViewModel(this)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val binding = DataBindingUtil.setContentView<ActivityLoginBinding>(this, R.layout.activity_login)
        val emitter: Subject<NoParameter> = PublishSubject.create()
        binding.loginButton.setOnClickListener { view -> emitter.onNext(NoParameter.INSTANCE) }
        viewModel.loginCommand.bindTrigger(emitter)
        binding.vm = viewModel
    }

Activity.kt(Fragment.kt) におけるPOINT

RxCommandはイベントの橋渡ししかしないのでClickListenerとの連携は独自で実装する。
これをやらないと実行時にDatabindingにてVoidからNoParameterの型違い関連のビルドエラーが出る。

ViewModel 

LoginViewModel.kt
val loginId = RxProperty<String>("")
            .setValidator { value -> if(value.isEmpty()) "必須項目" else null }
            .asManaged()

val loginCommand: RxCommand<NoParameter> = loginId.onHasErrorsChanged()
            .map { !it }
            .toRxCommand<NoParameter>(!loginId.hasErrors())
            .asManaged()

init {
    val d1 = loginCommand
            .doOnNext { progressAction.set(true) }
            .concatMap { invoker.login(loginId.get()) }
            .subscribe {
                progressAction.set(false)
            }
}

ViewModelにおけるPOINT

  • commandをプロパティで宣言するとき、入力チェックしたいRxPropertyのValidationと連動できる。
  • .map { !it } にて入力チェックが正常だったことを保証する。
  • toRxCommandでは初期値を渡す。
  • コンストラクタ(init)にて 後続処理のイベントストリームを作成し、プログレスバーの表示やAPI実行を繋ぐ。最終的にsubscribeが実行される。

Databindingカスタムセッター

準備中・・・

RecyclerViewでのMVVM

要調査

2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5