月別: 2015年11月

私がAndroid Studioで利用しているplugin

この記事は最終更新から3ヶ月以上が経過しています。情報が古い可能性があります。

Android Studioは常に最新を追いかけるんだ、なんてやっていた私ですが、最近ではそれもやや保守的になりつつあります。その理由の一つに、アップデートでプラグインを入れなおさないといけないというのがあります。

例えば1.4から1.5にバージョンを上げると、今まで使っていたAndroid Studioのプラグインは入れなおしになります。設定項目は引き継いでくれるのに、なぜプラグインは引き継いでくれないのか不思議です。マイナーバージョンアップによってプラグインが誤動作する可能性を考慮して、プラグインだけは引き継がないようにしてるのでしょうか?

Android Material Design Icon Generator

GoogleのMaterial Design Iconをプロジェクトに取り込むのに便利なプラグインです。

ちなみに余談ですが、Android Studio 1.4からVector Assetなる機能が追加されています。Vector Assetを使うとMaterial Design Iconを取り込むことができるのですが、これを使うためには条件があります。minSDKを21以上にするか、それができない場合はgradleのandroid pluginのバージョンを1.4以上にする必要があります。SDK21未満だとvectorを扱うことができないので、これをpngファイルとして書き出してやる必要があるのですが、それをするためにはandroid plugin 1.4以上が必要なのです。ちなみにgradleのandroid plugin1.4以上(これを書いてる時点では最新が1.5)はbeta版であり、気軽には導入できません。

結局Material Designのアイコンを取り込もうと思うと、こちらのプラグインを利用するのが楽なのです。

Dash

とりあえず入れてる系プラグイン。そもそも私自身がDashを使いこなせていないのが問題。

Fabric for Android Studio

Crashlyticsを導入するのに使っているというか、それ以外の使い方をよく知りません。発生したcrashなどを確認するのに便利なんでしょう、たぶん。

私の場合、アプリを作ったらそのまま放置してしまっているので、いかんなぁ、改善せんとなぁと考えているところです。たぶん、今後お世話になる機会が増えていくプラグインだと思います。

Genymotion

Android StudioからGenymotion使ったエミュレータを起動するのに使うプラグインです。

しかし最近は実機でデバッグすることが多いので出番があまりありません。動作の軽快なエミュレータといえど、貧弱な私の開発環境では実機で確認した方が早いんですよね。久しぶりに起動したらGenymotionがちゃんと動かないという状態になっていて、余計に出番が遠のいてしまいました。

IdeaVim

Android StudioでVimキーバインドを有効にするプラグインで、私の中でなくてはならないプラグインの1つです。

なんでもVimでやっちゃうようなバリバリ使いこなしてる人だと物足りなさがあるのかもしれません。しかし、私はなんちゃってVim使いなのです。カーソルの移動(行末に飛ぶとか)、次の行から入力を始めるとか、インデントを整えるとかいう操作をVimでやる程度です。

その程度の使い方ではありますが、これをvimでやると何が便利かといえば、Android Studioのキーボードショートカットを覚えなくてもすむことにつきます。それぞれのエディタ、IDEごとにショートカットを覚えるのは面倒くさい(というか覚えられない)ので、私はいつもVimキーバインドで代用するわけです。

Xcode、Visual Studio、MonoDevelop(Unity)などでもVimキーバインドで使おうとしましたが、それらに比べるとAndroid Studioの(というかInteliJの)Vimプラグインは素直で非常に使いやすい印象です(エディタとの競合が少ない、再現度が高い)。

Markdown

Markdownを書くプラグイン。特にこだわりがあって入れているわけではなく、一番ダウンロード数の多いものをとりあえず入れただけです。Markdownで書いて、HTMLでプレビューができます。

そもそもあまり使用頻度が高いわけではなくて、GitHubのREADME.md書いたり、ストア掲載文の草稿を書いたりするのに使う程度です。プレビューなくても問題ない使い方してるので、別に入れなくてもいいんじゃないかと思わなくもないです。

ラムダ式とは一体何なのか

この記事は最終更新から3ヶ月以上が経過しています。情報が古い可能性があります。

Java8から使えるようになったラムダ式はAndroidではそのままでは使えません。Android Studioが「ラムダ式で書いたらこうなる」と見た目だけ表示してくれたりしますが、実際にラムダ式でコードが記述されているわけではありません。

例えば、このようなボタンにクリックリスナーを設定するコードがあったとして、

mButton.setOnClickListener(new View.OnClickListener(){
    @Override
    public void onClick(View v){
        Log.d(TAG, "Click!!");
    }
});

Android Studioがラムダ式スタイルで見た目をすっきりさせてくれるわけです。

mButton.setOnClickListener((v) -> { Log.d(TAG, "Click!!"); });

これはエディタ上で折りたたまれて表示されているだけで、実際に記述されているコードは上のものです(マウスカーソルを上に持って行くと表示されます)。

で、これを本当にラムダ式で記述できるようにするライブラリとしてretrolambdaというものがあります。あるんですが、その前に、そもそも私はラムダ式自体がよく分かっていません。そこでまずは、ラムダ式とはなんぞやというところから調べることにしました。

ざっくりした書き方で、私の中のイメージを書き連ねたのでわかりにくいところがあると思います。間違ってるところもあると思いますが、その際はご指摘いただけるとうれしいです。(長い前置き終わり)

ラムダ式はいろいろ省略することのできる記法

ラムダ式はアロー演算子を利用して(引数) -> {処理}という書き方ができるものです。この書き方ができるのは一定の条件下においてですが、引数にOnClickListenerのような抽象メソッドが1つだけのinterfaceを取る場合と考えておけばいいと思います。

OnClickListenerは以下のように、onClickという抽象メソッドが1つだけ定義されたインターフェースです。

    public interface OnClickListener {
        /**
         * Called when a view has been clicked.
         *
         * @param v The view that was clicked.
         */
        void onClick(View v);
    }

これをsetOnClickListener()する際に、無名クラスとして定義して使っているわけですが、その無名クラスの定義をすっ飛ばして、直接抽象メソッドへの引数と処理だけを書くことができるのです。

なぜ省略できるか

なぜ省略して書けるかというと、まずsetOnClickListener()というメソッドは、引数にOnClickListenerというインターフェースをとります。そしてJavaのinterfaceという仕組みによって、onClick()というメソッドが必ず実装されていることが保障されます。すなわち、この中では少なくともonClick()というメソッドが呼ばれることがわかっているわけです。だから省略できるのです。

ラムダ式の左辺については、引数が1つであれば()を省略できたり、型を省略することができます。型を省略できる理由は、インターフェースの定義で型が決められているため、省略されても分かるからです。

右辺の{}はメソッドの中身が1文ですむ場合に省略可能です。また、return文だけですむ場合も同様で、さらにreturn句も省略できます。なぜならソッドの戻り値がインターフェースの定義で決められており、右辺の処理が戻り値を表していると自明だからです。

あくまでこれらは「省略できる」であって、別に省略せずに書いても問題ありません。(もっともわざわざラムダ式を使う目的を考えれば、省略できるところは省略すべきでしょうが)

それでも分からない人に、もしかしたら引っかかるかもしれない情報

省略して書けることは分かったけど、やっぱりラムダ式よく分からない。そんな人は、「そもそもなぜメソッド1つだけが定義されたinterfaceを用意して使っているのか」が分かっていないことが原因かもしれません(私はそうでした)。

ラムダ式が適用できるパターンが全てそうかは知りませんが、少なくともOnClickListenerについてはObserverパターンによる実装です。なぜメソッド1つだけのinterfaceを定義して使うかというと、「クリックされた」というイベントを監視するのに便利だからです。

イベントの発生を監視するためには、イベントの発生を通知する人が必要になります。そのときに監視側が「俺はnowClickメソッドで通知してくれ」、「僕にはclickメソッドで教えて」、「私はonClickメソッドで」とバラバラな実装になっていたらどうでしょう。こうなるとイベントを通知するクラスは、イベントを監視するクラスが増える度に通知処理を書き換える必要性に追われます。そんなのはナンセンスです。

そこで「うるせー! クリックイベントは今後OnClickListenerというインターフェースのonClickメソッドで通知する。異論は認めん!」と通知する側が決めてしまえば全てがすっきりします。

イベント通知側は監視者が誰であるかを気にする必要がなくなります。どんなクラスが通知を受けたがっているのか、どんなメソッドで通知して欲しいのかを考えなくてもよくなるのです。イベントが発生したときにインターフェースを介して通知すればいいだけなのですから。

受け取る側は、指定されたインターフェースを実装しさえすれば、イベント発生時にそのメソッドを通じてイベントの発生を検知することができるわけです。誰がイベントを通知してくるのかを考えなくても良くなります。実際、AndroidにおいてonClickメソッドを誰が通知してくるのか考えなくても処理できています(Androidがよしなにやってくれてるんでしょう)。

それをスマートに実現する方法が、メソッド1つだけ定義したinterfaceを使うことです。

私自身まだふわっとした理解なので、余計に混乱させてしまったら申し訳ないです・・・。

まとめ

  • ラムダ式は省略記法
  • OnClickListenerのような抽象メソッド1つのインターフェースで使える
  • そういうインターフェースはObserverパターンで使われる
  • なぜならイベントの発生・監視に便利だから

ラムダは単なる省略記法というわけではないのでしょうが、とりあえず今は単純に割りきって考えようと思います。単なる省略記法と思えば、ラムダ式への心理的なハードルがぐっと下がりました。最初の一歩としては「省略できるんだ」でいいんじゃないかと思います。ただし変な覚え方して後々困ることになるのかもしれませんが・・・。

ちなみにそんなラムダ式をAndroid Studioで使えるようにするライブラリが、gradle-retrolambda – GitHubです。(導入の仕方とかはここでは語りません、よく分かってないので)

参考

知っといてムダにならない、Java SE 8の肝となるラムダ式の基本文法 (1/3)

矢沢久雄の早わかりGoFデザインパターン(6) 第6回 Stateパターン/Observerパターン

RxAndroidとRetrolambdaで大体Java8をAndroidに持ち込む