カテゴリー: Android Studio

Settings Repositoryプラグインを使ってIDEの設定を共有する

いつもOverwrite local/Overwrite remoteが、どっちがどっちなんだっけと使うときに混乱するのでメモ。

どっちがどっち、というのはovwerwrite localが、現在の設定をリモートリポジトリの設定で上書きするのか、現在の設定でリモートの設定を上書きするのか混乱してしまうのである。
Overwrite localは現在の設定をリモートの設定で上書きする、が結論なんだけど。
これがわかりにくいと思うのは私の英語力がないせいなのだろうか。

Settings repositoryの設定について

ちなみにSettings Repositoryをご存じない方向けに簡単に紹介。

IntelliJ IDEAで使える設定共有用のプラグイン。
私の場合で言うと、Android Studio(stable/canary)とIntelliJ IDEA community editionを行ったり来たりすることがあるので、このプラグインを使って設定を共有している。
バージョンアップする際に以前の設定を引き継ぐというのはできるが、同時に運用しているときにAで行った設定変更をBでもまたやらないといけない、というのが起こらなくなるので非常に便利だと思う。

利用しているプラグインによっては、そのプラグインの設定ファイルもバックアップ対象になるらしい。
例えば私はIdeaVimを利用しているが、どのファイルのどの位置にカーソルが移動した、という情報までバックアップ対象になってしまっている。
そのため必要に応じて不要な設定ファイルは.gitignoreで管理対象から外すなど工夫が必要。
(私はvim_settings.xmlは管理対象から外している)

MacであればFileメニューのところにSettings Repositoryがあるので、GitHubなりBitbucketなりで管理用リポジトリを用意してそのURLを設定すれば使えるようになる。

ちなみにどうもエディタでタブを使わないとか、キーマップの設定でどれを使うかなどまでは合わせてくれないようだ。
例えば私の使っているキーマップはMac OS X 10.5+ copyとなっているのだが、このキーマップ設定自体は共有してくれるものの、これが有効な状態にまでは復元してくれない。
そのため、どのキーマップを使うか、コードスタイルはどれを使うかなどは手動で直さないといけないようだ。

こう書いたらこう動くよねを確認するためにユニットテストを活用する

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

私はわりとカジュアルにユニットテストを使っている(と思う)。クラスやメソッドの振る舞いをテストするさらに前段階の状態で使っている。

「こういうコードを書いたらこうなると思ってるんだけど、合ってるよね?」というのを確認するためのテストコードをユニットテストに書いてしまうのである。ノイズにしかならないので、普通はこんな使い方しないと思うが、Androidの文脈においていちいち端末で実行して動作を確認するよりは早いと思っているので、個人的には便利に使っている。

実例

上記のリポジトリでは、ThreeTenAbpの使い方を確認するテスト用のコードなんかが散らばっているが、こんな感じでライブラリの動作を確認したり、最近だとRxJavaでOperatorを連結した処理の確認をしたりするのにユニットテストを利用している。

testディレクトリに適当なクラスを作って、そこでJUnitスタイルで動きを確認したいコードを書くだけである。

私はKotlinでコードを書くことが多くなってきているので、Kotlinの拡張関数の動きを確認するためにユニットテストを活用していたりする。例えば空文字をsplit()したときにサイズがどうなるのか、なんてのを確認したりするわけだ。

class StringSplitTest {
  @Test
  fun split_empty() {
    val test = "".split("\t")
    test.size.should.equal(1)
  }
}

このコードではexpektというライブラリを使ってアサーションを行っている。

実装を追えよという話ではあるのだけど、ふとした疑問をさっと確認するのには便利だと思うのだけどどうだろうか。わざわざ実機なりエミュレータ上で実行して、デバッガで確認して・・・なんてするよりは絶対に早い。

たぶんチームで開発しているとかいう状況だと、こんなテストコードが残されると邪魔でしかないと思うが、個人的に確認する分には弊害はないだろう。消すのを忘れてコミットしちゃうおそれがあるとか、そんなレベルの話。

私の場合はぼっちで開発しているので、こういうレベルでもテストコードを書いていれば、ユニットテストのやり方の勉強にもなっていいかなと思っている。

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'])を追加すれば組み込めると思います。

ライブラリの取り込み