カテゴリー: Android Studio

Save Actionsというプラグインに感動した話

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

DroidKaigi2017の会場には行かなかったけれども、参加した人や公開されたスライドなんかは一通りチェックしている。そんな中でこちらのスライドでSave Actionsなるプラグインを知る。

少し幸せになる技術

Android Studioで保存時にフォーマットを自動で揃える

Save Actions – JetBrains Plugin Repository

Save Actions – GitHub

Android Studioでビルドしたりファイルの保存が行われた際に、自動的にoptimize importやreformat codeを実行してくれるプラグインである。

ファイルの保存時にrefomart codeを実行する方法として、cmd+sにマクロを割り当てて行うという方法は以前から知っていたのだが、私は導入していなかった。というのも、私はAndroid Studioを使っていてただの一度も自分からファイルの保存を行ったことがないからである。そもそもcmd+Sを押す習慣がなかったのだ。それだったら気がついたときにalt+cmd+lでreformat codeを実行するのと大差ないなと思って導入しなかった。なのでreformat codeを実行することもよく忘れていた。(droidkaigi2017のリポジトリにフォーマットしてないコードをプッシュしたりしていた、申し訳なかった)

しかしこのSave Actionsプラグインに出会えたことで、今後そんなミスは起こさないだろう。

このSave Actionsは、Android StudioのPreference > Pluginsからは検索することができない。作者の方がAndroid Studioによる動作確認が取れていないのがその理由らしい。

導入するにあたっては、JetBrainsのPlugin Repositoryからzipファイルをダウンロードしてきて直接インストールする必要がある。

ちなみに、今のところAndroid Studioだからきちんと動作をしないという事象には出くわしていない。

素晴らしいなと感じたのが、ファイルが自動保存されるタイミングやビルド(デバッグ実行)したタイミングで、自動的にreformat codeが走ってくれること。しかもそのSave Actionsのreformat codeで修正された部分は、自分が修正したコードとは異なる色で表示される(新規が緑、変更が青、Save Actionsによるreformat分はグレーみたいな感じで色分けされる)。あくまでAndroid Studioのエディタ上での表示の話なので、コミットする際に別れてくれるわけではないけれども。

なお、Save Actionsを導入する場合は、必ずFile path exclusionsに.gradleファイルを追加する必要がある。

https://github.com/dubreuia/intellij-plugin-save-actions/issues/51

Gradleファイルをいじる際に、キーをタイプするたびにreformat codeなどが走るというバグがあるからだ。

個人的にはプラグインのバグというより、IntelliJ系IDEの仕様なのではないのかと思っている。gradleファイルはspaceを追加するだけでも「syncしろ」と言ってくるので、このあたりの動きが関連しているようにも思う。ともあれ、当座のところはgradleファイルをSave Actionsの対象外にすることでしのげる。

ともあれ、個人的にとても便利なプラグインだと思う。あまりに感動して作者にお礼のツイートを送ってしまうほど、ドンピシャなプラグインだった。

少し幸せになる技術というスライドで紹介されていたが、私は少しどころではなくかなり幸せになれた。ありがたい。

はてなブックマークのホッテントリリーダーを作った

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

勉強がてらホッテントリリーダーを作ってみました。ソースコードはGitHubで公開しています。

アプリも公開中です。

Get it on Google Play

自分の勉強のためというのが目的のアプリです。最初はDagger2に慣れるために適当に遊んでいたのですが(その名残が微妙に残っている)、それをちゃんとしたアプリに落とし込んだときに使いこなせるのかという不安がありました。そこでアプリとして動くものを作ろうと考え、じゃあいっそいろいろなライブラリを使いながら勉強しようと、このような形になりました。

とりあえずアプリとして動くところまではできたので、Google Playで公開してみました。アプリ名をもうちょっとひねろうかと思ったのですが、思いつかなかったのでそのままな名前をしております。

公開している部分にはまだ含まれていませんが、Dagger2でモジュールを差し替えて通信をモックしたり、テストコードを加えたりといい勉強になっています。そのあたりもそのうち公開できたらなと思っています。

Dagger以外にもRetrofitをはじめて使ってみたり、いい勉強になっている気がします。

テスト周りとかCIの勉強も出来たらなぁと考えています。

Instrumentation Testで生成されるAPKは何をしているのだろう

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

以前、Viewの描画をテストするためのリポジトリを作りました。記事はこれです。

Viewが想定通り描画されているか確認するため、Spoonを使ってスクリーンショットを撮るようにしました。GitHubにあげたコードでは、TextViewの周りに枠線を描画するCustomViewを作成し、その枠線が描画されるかを確認するというものでした。

しかしSpoonで撮ったスクリーンショットでは、右側と下側に描画されるはずの線が表示されていません。実機で動かすと描画されているのですが、スクリーンショット上では見えない。

Spoonのバグなんじゃないかななんて最初は思っていたのですが、調べてみると原因は違うところにありました。いえ、Spoonのせいではないということはわかったのですが、じゃあなぜそうなるのかというところが分からないので困っている状態です。

Spoonのスクリーンショットで線が描画されない理由は、右と下の線が画面外に描画されてしまっているからです。

CustomViewは右側・下側に描画する位置を、onDrawメソッドの引数で渡ってくるCanvasのサイズ(canvas.getWidth()canvas.getHeight())を使って描画しています。

実機で実行した場合、ここに渡ってくるCanvasのサイズは、CustomViewと同じサイズになっているようなので、TextViewの周りに枠線が描画されます。

一方で、androidTestで実行した場合、このcanvas.getWidth()で得られる数値は、想定したものよりはるかに大きい数値になります。数値の大きさから察するに、画面全体と同じ大きさになっているような気がします。

実機で実行した場合:

10-05 17:35:09.972 1992-1992/jp.gcreate.sample.viewdrawingtest.uiTest D/test: canvas:android.view.GLES20RecordingCanvas@30073153, height:96, width:983
10-05 17:35:15.412 1992-1992/jp.gcreate.sample.viewdrawingtest.uiTest D/test: canvas:android.view.GLES20RecordingCanvas@2a498faf, height:96, width:983

androidTestで実行した場合:

10-05 17:37:37.955 3888-3888/jp.gcreate.sample.viewdrawingtest.uiTest D/test: canvas:android.view.GLES20RecordingCanvas@375e49fb, height:1436, width:983
10-05 17:37:37.982 3888-3888/jp.gcreate.sample.viewdrawingtest.uiTest D/test: canvas:android.graphics.Canvas@1cad5ead, height:1919, width:1079

androidTestで実行すると、渡ってくるCanvasが実機の場合と異なるようです。

onDrawメソッドで渡されるCanvasとは一体何なのかという点についても、私はよく分かっていないのですが、androidTestで実行されるtest用のAPK(この場合app-UiTest-debug-androidTest.apk)が何をやっているのかもよく分からなくなってきました。

androidTestを実行すると、実機上に画面が表示され、テストコードに書いた動きが実行されていくので、それは全てtest用のAPKで実行されているのだとばかり思っていました。しかしそう考えると、実機で表示されている画面では枠線が描画されているのに、Spoonで撮影したスクリーンショットには映っていないことの理由が説明できません。

そんなことを考えていると、Instrumentation Testとは一体何なのかがよく分からなくなってきました。

Android Studio2.2でProject Windowのパッケージ名表示が省略されない

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

タイトルが分かりにくいんですが、こちらの画像をご覧ください。

パッケージ名が省略されない

画像の例ではアプリのパッケージ名がjp.gcrete.sample.daggersandboxで、そこからさらにapiとかdiとかのパッケージに分化してます。

Android Studio2.2にしてから、なぜかそのサブパッケージの部分が単にapiではなく、jp.gcreate.sample.daggersandbox.apiと省略されずに表示されていました。

Layout EditorのようにAndroid Studioの設定でそうなっているのかとも思いましたが、該当するような設定項目はありませんでした。

なんでだろうなと思って探してみたところ、issueが立ってました。

https://code.google.com/p/android/issues/detail?id=223389

https://code.google.com/p/android/issues/detail?id=222914

どうもDataBindingを有効にすると発生するそうです。実際、この画像のプロジェクトでもDataBindingを使っており、これをfalseに変更すると普段通りの表示になりました。

DataBindingTrue

DataBindingFalse

DataBindingを使っている人のみ影響を受けるみたいです。

最近はfindViewByIdを使わなくて済むからくらいの軽い理由で、DataBindingを多用しているので早く直ってほしいです。

まあProjectウィンドウが見づらくてなんか気持ち悪いってだけなんですけどね。

Android Studio 2.2.1で直ったみたいです。

Android Studio2.2でレイアウトエディタを開いた際にTextで開くようにする

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

layout.xmlを開いた際に、デフォルトではDesignタブで開かれると思います。これをTextに変更する方法です。

Android Studio 2.1まではレイアウトのPreview画面に歯車アイコンがあって、Prefer XML EditorにチェックをつければOKでしたが、Android Studio 2.2のPreview画面にはそのようなものが見当たりません。

Android Studio 2.2からは、設定画面から変更するようです。

レイアウトエディタをTextで開く

Preference > Editor > Layout Editorで設定できます。

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

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

以前から作ってみたいなぁとは思っていたのですが、このたびやや必要性が増したこともあって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を使って作りました。既にやってくださっている方がいらしたので非常に助かりました。

KotlinとGradleで始めるAndroid Studioプラグイン開発

Kotlinを使った理由は、そんなに深い理由があるわけではありません。単に直前に作っていたアプリでKotlinを使った開発をしていた影響です。正確にはJDK1.6による開発のため、ラムダ式とか使うのにバックポートライブラリを入れるよりはKotlin使ったほうが楽かなとか、Javaで書いたときにセミコロンつけるのが面倒くさかったとか、そんな感じです。

Gradleを使ったのは、依存関係の処理に困ったからです。jarを拾ってきてlibフォルダに入れたらなんとかなるんでしょうが、どうやればいいのかがよく分からなくて、少しでも慣れているGradleを使いたかったのです。

最近読んだAndroid Studio本格活用バイブルのおかげで、「この.imlファイルを削除しても、最悪Gradleから復元できる」みたいなことが分かっていたのが大いに役立ちました。

GitHubで公開中

ソースコードはGitHubで公開してあるので、ご意見ご感想待ってます。

細々した問題はあるものの、一応動くと思います。多分。

正直な所、自分以外の環境だと動くのかどうか分からないので、動いた・動かないの報告をいただけるだけでもありがたいです。

参考サイト・情報

参考にさせていただいた方々に感謝を。

初めてのAndroid Studioプラグイン開発入門

KotlinとGradleで始めるAndroid Studioプラグイン開発

IntelliJ Platform SDK Documentation

AdbCommander for Android – BitBucket

ADB Idea – GitHub

Android Material Design Icon Generator – GitHub

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

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

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

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

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

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

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

式の即時評価

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

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

どんなときに便利か

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

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

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

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

try-catchで止めてみる

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

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

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

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

この記事は最終更新から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書いたり、ストア掲載文の草稿を書いたりするのに使う程度です。プレビューなくても問題ない使い方してるので、別に入れなくてもいいんじゃないかと思わなくもないです。

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

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

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上でだけですが、他の部分でも影響があるのかもしれません。