LoginSignup
2
1

More than 5 years have passed since last update.

Zaif公式Androidアプリが微妙だったのでKotlinの勉強を兼ねて通貨ペアViewerアプリを作った

Last updated at Posted at 2018-01-23

はじめに

なんだかんだで体調を崩してしまい、2018年1月は仕事をお休みしてました。
がそろそろ、リハビリ兼ねてKotlinの勉強をしようと考え、Zaifの仮想通貨ペアViewerアプリを作りました(題材をZaifにしたのは公式アプリがお粗末なでk・・・ゲフンゲフン)。こんなやつ↓

Group.png

左の一覧ページの方は10秒毎(ZaifAPIはリクエスト数に制限があり、かつ、一括で終値を取得できないのでこんな仕様にorz)に終値をとってきていて、個別ページの方はWebSocketでリアルタイムに更新しています。今回はKotlinで作った上でJavaとの相違点、躓きそうなポイントをまとめてみました。

お急ぎの方はGitHubにコードを公開しているので下記からどうぞ
https://github.com/tarumzu/ZaifClientAndroid

躓きポイント① Java時代にお世話になってたButterKnifeが必要ない!

多くの方々がお世話になったであろうButterKnifeですが、必要ありません!!
というのは言い過ぎですが、バインドしてあげなくともKotlin Android ExtensionsというKotlin標準の機能で直接Layoutの要素を取得することが出来ます。こんな感じ。

activity_main.xml
/ 省略 /

    <android.support.v4.widget.SwipeRefreshLayout
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        android:id="@+id/swiperefresh"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >

/ 省略 /
MainActivity.kt

import kotlinx.android.synthetic.main.activity_main.*

/ 省略 /

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // xmlで定義したIDで取ってこれる!
        swiperefresh.setOnRefreshListener({
            Timber.d("onRefresh called from SwipeRefreshLayout");
            initiateRefresh();
        });

/ 省略 /

ただ、ViewHolderなど特定の変数に紐付けたい場合があったり、イベントのバインドは出来ないという不便さもあるのも事実。そういった場合はKotlin用のKotterKnifeを使うのも手です。
https://github.com/JakeWharton/kotterknife

躓きポイント② WebSocket!

これはKotlin関係ありません!w
完全に自分の経験不足のものです。Kotlinを勉強しながらAndroidアプリでのWebSocketの使い方も調べて行きました。実際にやってみたところ、Okhttpで簡単に実装できました!w

DetailActivity.kt
/ 省略 /
        private inner class EchoWebSocketListener : WebSocketListener() {

            override fun onOpen(webSocket: WebSocket, response: Response) {
                Timber.d("open")
            }

            override fun onMessage(webSocket: WebSocket?, text: String?) {
                Timber.d("Receiving : " + text!!)
                var currencyPairStream = mGson.fromJson(text, CurrencyPairStream::class.java)

                activity.runOnUiThread({
                    price.text = if (currencyPairStream.lastPrice != null) {
                        currencyPairStream.lastPrice!!.price.toString()
                    } else {
                        currencyPairStream.price.toString()
                    }
                })
            }

            override fun onMessage(webSocket: WebSocket, bytes: ByteString) {
                Timber.d("Receiving bytes : " + bytes.hex())
            }

            override fun onClosing(webSocket: WebSocket?, code: Int, reason: String?) {
                webSocket!!.close(1000, null)
                Timber.d("Closing : $code / $reason")
            }

            override fun onFailure(webSocket: WebSocket?, t: Throwable?, response: Response?) {
                Timber.d("Error : " + t?.message)
            }

        }
/ 省略 /

            val request: Request = Request.Builder().url(getString(R.string.api_ws_base_url, mCurrencyPair)).build()
            mWebSocket = mZaifClientWSOkHttpClient.newWebSocket(request, EchoWebSocketListener())

            // TODO: 調べた感じ不要な気がする。詳しい人教えて下さいm(_ _)m
            //mZaifClientWSOkHttpClient.dispatcher().executorService().shutdown()

躓きポイント③ KotlinとJavaの構文のちがい

当然のごとく多くの方が躓いており、偉大な先人様の記事が大変参考になりました。個人的に一番戸惑ったのはnullの扱いですかね〜。Javaとは異なり、KotlinはデフォルトでNullを許しません。(?つかったり?:つかえばNullも扱えますが、そこは賛否両論あるところ…)
https://qiita.com/koher/items/bcc58c01c6ff2ece658f

最後に

まだまだこのアプリを使いやすくしたいな〜と考えてます。買い板、売り板表示させたり、実際に売買出来るようにしたり。APIの都合上チャートは難しそう。
頑張りますかね〜。

2
1
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
1