Kotlinを使っていて感じるつらさ

ちなみにこの記事を書いたのはかなり昔のことなので、今はだいぶ環境が変わっている。マシンスペックによる辛さも含まれていたので、現在ではだいぶ解消されていると思って読んで欲しい。

なにせ3年もまえの記事だからね・・・あんまり真に受けないように。19年時点の私はだいぶKotlinラバーですから。

Read full post gblog_arrow_right

Android Studio用のプラグインADB Friendlyを作ってみた

以前から作ってみたいなぁとは思っていたのですが、このたびやや必要性が増したこともあってAndroid Studio用のプラグインを作りました。

作成時間の半分くらいは環境構築に手間取っていたと思います。

ソースコードはGitHubで公開していますが、クローンしてもそのままビルドしたりできるのかよく分かりません。一応自分でgit cloneして確認したりしてみましたが、Androidのプロジェクトと比べると一手間必要で面倒くさい感じです。

参考にさせていただいたプラグインはほぼほぼgit cloneしただけでは動かせなかったので、Gradleは偉大だなということを再認識しました。

ADB Friendly

ADB Friendlyという名前ですが、現状では端末の画面を回転させることしかできません。どんな感じかはYouTubeをご覧ください。

私は端末の画面を回転させながらメモリ使用量のグラフを見て、作成したアプリがメモリリークしていないかどうかを確認することがあります。グラフが右肩上がりに上がり続けていると、それはメモリリークが発生しているということです。

今までは端末を手に持って、縦横縦横・・・とやっていました。ところがつい最近、こんなものを買いました。Macbookのモニタ横に、スマホを固定するクリップです。

Twitterのタイムラインで見かけて一目惚れして買いました。実に便利です。

便利なのはいいのですが、モニタにスマホを固定していると、画面を回転させることができません。そもそも手で画面回転させるのも面倒くさいです。そこでプラグインを作ってやることにしたわけです。

環境構築が大変

参考にさせて頂いたサイトは最後にまとめました。偉大な先達たちに感謝です。

私はSDKを準備するところからつまづきました。開発に使っているのはIntelliJ IDEA 2016.1.1になるのですが、このバージョンをもとにIntelliJ Platform Plugin SDKを作るとInternal Java Platformに1.6を指定することができませんでした。

これに関しては開発に使うIntelliJと、SDKに使うIntelliJのバージョンは別物であると考えたほうがよいのだと思います。

IntelliJ Platform Plugin SDKを追加するには、プラグインを作るにあたって対象とするバージョンのIntelliJ IDEAを別途インストールし、それを指定してやるのが正しいのだと思います。

プラグインを作成する際に、AndroidでいうminSdkVersionのような指定がIntellij pluginにもあります。(私の場合<idea-version since-build="141.0"/>と指定しました)

このバージョンはIntelliJ14.1を意味するので(参考:Build Number Ranges)、実際にコーディングする最新のIntelliJとは別に14.1.6をダウンロードしてインストールしました。

Previous IntelliJ IDEA Releases

また、プラグインを開発していくにはソースコードがないとつらいと思います。別途IntelliJ-Community – GitHubをクローンしてソースコードを入手しておく方がいいでしょう。ちなみにcloneする際には自分がSDKに指定したブランチになっているかを確認しましょう。SDKで利用するclassファイルとソースコードの中身で食い違いが生じて余計に混乱します。

ソースコードをアタッチ

正直な所、公式のDeveloper Guideはお世辞にも分かりやすいとはいえないので、ソースコードとすでにある先人たちのPluginこそがお手本でした。

Kotlin + Gradle

このプラグインはKotlinとGradleを使って作りました。既にやってくださっている方がいらしたので非常に助かりました。

Read full post gblog_arrow_right

式の即時評価を利用してオブジェクトの状態を調べる

式の即時評価が便利だよねという話です。

私は以前Calendarクラスを使って日付の処理をしようとしていました。そのとき、どのフィールドを参照すれば目的の値が引っ張ってこれるかを確認するのに、愚直にLog.d()を使っていました。1つ1つメソッドの返り値を出力して(文字列の連結でさらにカオスになる)、目的の数値がちゃんと取れているのか確認していたのです。

ドキュメントを読めよっていう話なんですが、読んでもどういう値が取れるのかいまいち分からなかったんですよね・・・。

まあそんなアホなことをやっていたので、当然のようにバグを仕込んでいました。そんなバグに気づくきっかけとなったのが式の即時評価機能です。以来、とてもお世話になっています。

式の即時評価を使えば、ブレークポイントを設定してデバッグ実行するだけで、任意のメソッドや変数の確認ができるようになります。

式の即時評価

メソッド呼び出しとその結果が確認できる

ブレークポイントで一時停止させないと使えないので、状態の変化を追うのには向かないかもしれません。それでもlogcat頼みのデバッグより捗る場面があると思います。

どんなときに便利か

今日遭遇したエラーで、なんかのタイミングでNullPointerExceptionが発生してクラッシュする現象が発生しました。

特定の状況で例外発生によるクラッシュ

例外の発生する箇所はわかっているものの、どういう状況でそれが生じているのかがよく分かりませんでした。

そこで例外の発生する部分をtry-catch文で囲み、例外をキャッチした所にブレークポイントを置いて調べてみることにしました。

try-catchで止めてみる

ブレークポイントで止めればコールスタックを遡ってオブジェクトの状態を確認できますが、目当ての変数を探すのが大変なので、そういうときに式の即時評価が便利です。だと思います。

jarファイルで配布されているライブラリをAndroid Studioで取り込む

Android StudioはビルドツールにGradleを使っているので、ライブラリはbuild.gradleのdependenciesに書くことで簡単に取り込むことが出来ます。

しかし、ライブラリによってはjarファイルで配布されているものもあります。(この例ではNiftyのMobile backend)

jarで配布されるライブラリを組み込む手順は簡単です。app/libsディレクトリにjarファイルを置くだけで完了です。

これはapp/build.gradleにて、libsディレクトリにあるjarファイルをビルド時にコンパイルするよう指定されているからです(compile fileTreeの部分)。

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.+'
    compile 'com.android.support:design:23.+'
}

libsディレクトリなんかない、という場合、プロジェクトビューがAndroidになっている可能性が考えられます(デフォルトではAndroidになっています)。この場合、Projectに表示を切り替えることでディレクトリ階層が表示されるようになるはずです。

それでも見つからなければappディレクトリの下にlibsディレクトリを作成し、app/build.gradleにcompile fileTree(dir: 'libs', include: ['*.jar'])を追加すれば組み込めると思います。

ライブラリの取り込み

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

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つです。

Read full post gblog_arrow_right

AndroidManifest.xmlでコード補完機能を使う際に注意すべきこと

Android Studioのコード補完機能を過信しすぎてはよくないというお話です。

例えば、AndroidManifest.xmlにpermissionを追加するときのことです。<uses-permission android:name="android.permission.INTERNET"/>を追加しようとしたさいに、Android Studioのコード補完に任せると<uses-permission android:name="ANDROID.PERMISSION.INTERNET"/>となることはないでしょうか。しかもAndroid Studioで補完された文字列だから、大文字のままでも問題ないのかなと放置していないでしょうか。

実はこれが全部大文字になっているとうまく動きません。android.permissionの部分は小文字でなければなりません。

原因と対策

これはコード補完で候補を絞り込む際に、INTERNETの部分を大文字でタイピングしたときに起こります。最初の1文字目を大文字でタイピングすることで、選んだ選択候補の文字列がすべて大文字で入力されてしまうようです。

この対策は実はとても簡単なことで、internetと小文字でタイピングして絞り込むことです。

INTERNETの部分が大文字だから大文字で入力しなければならないと思い込んでいないでしょうか。私は思い込んでました。なぜなら、コード補完で絞り込む対象が定数である場合、少なくとも最初の1文字目は大文字でタイピングしないと絞り込めなかったからです。だからpermissionでも同じなのだろうと思ってました。

しかし、このpermissionの場合は小文字でタイピングしても絞り込めます。そして、小文字で絞り込んだ場合だと正しくandroid.permission.INTERNETと入力されます。

定数だとなぜ大文字で入力しなければ絞り込めないか

これはAndroid Studioの設定によるものです。デフォルト設定がどうなのかはよく知らないので、人によって違うかもしれません。

Android Studioのコード補完機能の設定で、大文字・小文字を区別する設定があります(Preference > Editor > General > Code Completion)。私の場合はここが「First letter」になっています。そのため補完候補の最初の1文字目だけは大文字・小文字が区別されてしまうのです。

Android Studioのコード補完機能設定

そのため定数(例えばREQUEST_CODEといったもの)の場合、少なくとも最初のRだけは大文字で入力しなければ候補に残りません。一方でandroid.permission.INTERNETの場合は最初の1文字目が小文字であるため、INTERNETの部分で絞込をする場合に入力する文字は小文字でも問題ないのです。

今のところ私が遭遇して実際に影響を受けたのはAndroidManifest.xml上でだけですが、他の部分でも影響があるのかもしれません。

Android StudioでJunit4によるテストを走らせる

基本的にはここに書いてあるとおりにやればいいだけの話です。

準備

/app/build.gradleのdependenciesにjunitを追加します。

testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-core:1.9.5'

この際に注意が必要なのは、androidTestCompiletestCompileは別物であるということです。

何が別物かというと、テストコードを配置するディレクトリがそれぞれ違います。

その名の通りandroidTestCompileandroidTestディレクトリに配置したテストコードのコンパイル時にだけ使うライブラリです。同じくtestCompiletestディレクトリに配置したテストコードのみに使われるライブラリになります。

なお、androidTestディレクトリは自動的に作成されていますが、testディレクトリは自分で作らなければなりません。(ディレクトリは/app/src/test/java/パッケージ名にしてやればOK)

androidTestとtestの切り替え

Build Variantsウィンドウを開くと、Test Artifactという欄があります。

Build VariantsのTest Artifact

Android Instrumentation Testsを選択していると、androidTestディレクトリ以下にあるテストコードが有効化されます。有効化されるというのが適切なのかは分かりませんが、Android Studioからコンパイル対象のソースコードであると認識されます。

Unit Testsに切り替えると、testディレクトリが有効化されます。試しに切り替えてみると、androidTestディレクトリの色が変わって、テストコードのアイコンに赤いJアイコンが出るようになると思います。

IDE上からテストを実行しようと思うと、このBuild Variantsをいちいち切り替えないといけないのが面倒くさいかもしれません。

しかし、ターミナルからGradleを使って実行する場合は、このTest Artifactsの切り替えはしなくてもいいみたいです。Gradleからテストを実行する場合、./gradlew connectedAndroidTestがAndroid Instrumentation Testsを、./gradlew testがUnit Testsを選択してテストを実行するのと同じになります。この場合のテスト結果は/app/build/reports/testsの中に出力されます。

テストコードはViewやActivityなどのUIに関するテストをandroidTestディレクトリに、純粋なJavaコードのテストはtestディレクトリに置くように工夫すべきでしょう。そうしてやれば、ユニットテストにかかる時間を削減できて幸せになれると思います。

Android StudioでLogcatをフィルタリングする

Logcatでアプリのデバッグをする際に、自分のアプリからのログ出力だけ見たいなんてときありますよね。

そんなときにどうやってフィルタリングをするかという話です。

キーワードやログレベルでのフィルタリングはここでできます。

ログレベル・キーワードでフィルタリング

ちなみにログレベルでのフィルタリングは、指定したレベル以下のものを出力するというフィルタ設定になります。

例えばここでInfoを選ぶとInfo以下のものだけが出力されるようになり、VerboseとDebugレベルのログは表示されなくなります。

ログレベルは下図で囲った部分です。ログレベル/タグという形式で出力されています。

ログレベル

特定のアプリからのログ出力だけ見たい場合は、Show only selected applicationのところをクリックして、Edit Filter Configrationを選びます。

Edit Filter Configration

ここでPackage Nameのところで調べたいアプリのパッケージ名を指定してやると、自分のアプリからの出力しか表示されなくなります。

Package Nameでアプリからの出力のみに絞れる

こういったフィルタリングの設定をうまく使えば、アプリ開発も捗ると思います。

一方でLogcatにこれらのフィルタ設定をしているときには注意しなければならないことがあります。それは、アプリが落ちた時のスタックトレースまでフィルタされて表示されないことがあるということです。

「アプリが落ちたのにLogcatに何も表示されない・・・」と混乱しないようにしましょう。

Android StudioでQuick Documentationを活用する

Android Studioでコーディングしていて、「このメソッドどういう処理するんだっけ?」と思った時に便利なQUICK DOCUMENTATIONがあります。

F1押すと出てきますが、標準だとFloating Modeで表示されて邪魔です(設定によって違うかもしれませんけど)。

Floatingモードで表示されて邪魔

これは右上の歯車マークをクリックして、Floating Modeを押して解除してやれば他の枠に収まってくれます。

Floating Modeを解除

私の場合毎回右側にDocumentationが収まるのですが、右側は個人的に見づらい。このDocumentationはドラッグすることで表示位置を移動することができます。

個人的には右下に置いておくのが好みです。

表示位置は調整可能

こうすることでQuick Documentation機能がぐっと使いやすくなります。

これでめでたしめでたしなんですが、このままではDocumentationの表示位置は現在開いているプロジェクト固有の設定にしかなりません。

つまり、別のプロジェクトを作成してQuick Documentationを利用した時に、再びFloating Modeで開かれてしまいます。プロジェクトごとに毎回この設定をするのは面倒なので、これを標準のレイアウトとして設定してしまいましょう。

方法はAndroid StudioのWindowメニュー→Store Current Layout as Defaultを選べばOKです。

標準のレイアウト設定にしてしまう

これで毎回設定せずともすみます。

Android Studioでソースコードを読むのに覚えておくと便利なショートカット

最近になってようやくサンプルなどのソースコードを読むようになったのですが、「あ、こんな便利な機能あったのね」というのを紹介します。

ショートカットキーはMacのものを書いてます。メニューにショートカットキーも表示してくれているので、Windowsの方はそこで調べてください。

Find Usages

調べたい変数やメソッドにカーソルを合わせてOpt+F7

Edit > Find > Find Usages

変数やメソッドがどこでどう使われているか調べるのに使います。今まで右クリック→Find Usagesで表示させてました。もしくはIdeaVim使っているので「/文字列」で検索してました。

メンバ変数(フィールド変数)だとValue readでどこで参照されているかが、Value writeでどこで変更されているかが表示されます。

フィールド変数でFind Usages

メソッドだと、どこで呼ばれているかが表示されます。

メソッドでFind Usages

プライベートフィールドに対して特に効果を発揮する機能です。

ちなみにFind Usagesで使われ方を表示した後は、Cmd+Shift+↓(↑)で次に出てくるところに飛んでくれます。さらにいうとCmdとOptを押し間違えると、表示させてる行の位置が入れ替わったりするので注意してくださいね。

戻る

Cmd+[

Navigate > Back

日本語キーボードだと[ではなく@になります。

Find Usagesなどを使ってジャンプした場合に、ジャンプ前に読んでた場所に戻ってくれます。今まで「前読んでたところどこだ・・・」とイライラしながら探してました。

戻りすぎたらCmd+](日本語キーボードなら[)で1つ先へ飛びます。

この機能を使わずしてソースコードは読めない。

とりあえずこの2つの存在を知っているだけで格段にソースコードを読む辛さが緩和されます。

Declaration

Cmd+b もしくはCmd押しながらクリック

Navigate > Declaration

私はDeclarationの意味をよく分かってないのですが、宣言先に飛ぶってことなんだと思います。

親クラスで定義されてるメソッドを呼んでる時に、そのソースコードに飛ぶときに使ってます。例えば何気なく使ってるfindViewById()はいったい何やってんだって調べたりする感じです。Cmdキー押しながらクリックするだけなんで、ショートカットキー覚えてなくても行けそうな気はします。

Android Support Libraryのクラスだとソースコードまで付属してないのでそのままでは見れないんですけどね(見れないわけではないようです)。

Android標準のクラスならソースコードもインストールしてあれば確認することができます。Android SDK ManagerでSources for Android SDKをインストールしておく必要がありますが、開発する上ではないと困ると思うのでインストールしておいた方がいいでしょう。

SDK ManagerでSources for Android SDKをインストールしておく

Javadoc表示

Javadocを確認したいメソッド等にカーソルを合わせてF1Shift+F1でブラウザで見れます)

Read full post gblog_arrow_right