Droidkaigiのリポジトリを参考に自分でGradle Pluginを作成してみる

Droidkaigiのリポジトリのように、マルチプロジェクトで設定ファイルを共有する仕組みを知りたいと思って幾星霜。

今まで重い腰が上がらなかったのだが、Wear OSのプロジェクトが設定をベタ書きにしており非常につらい思いをしていたので、必要に迫られてやることにした。誰かの参考になれば幸いである。

Read full post gblog_arrow_right

ライブラリのバージョン管理をしやすくするrefreshVersionsを試してみた

Gradleでライブラリの管理を便利にできそうなプラグインを見かけた。refreshVersionsというプラグインだ。

buildSrcを使って一括管理する方法は知っていたが、プロジェクトごとに用意するのも面倒くさい。なにか楽な方法はないかと思っていたが、これはその解の1つとなりそう。

Read full post gblog_arrow_right

Floobitsを試してみた

Floobitsというのはリアルタイムコラボレーションを実現するためのサービス。 VSCodeのVisual Studio Live Shareみたいなやつで、リモート経由でのペアプログラミングとかを実現するためのサービスである。 リモート経由でペアプロしたいが、Android開発でそんなことできるのかというのが出発点だった。 Android StudioのベースとなっているIntelliJ IDEAでもそういう機能があるのか調べたところ、今の所ないというのが結論。 要望自体ははるか昔からあるみたいだが、実現するにはコラボレーション用のサーバ用意したりとハードルがあまりに高いだろうことは想像に難くない。 公式には用意されていないが、見つけたのがこのFloobitsというサービスである。 別にIntelliJに限らず、他のプラットフォームでもプラグインが用意されている。 https://floobits.com/help/plugins Emacs, Sublime Texxt, Neovim, IntelliJ, Atomと多数のエディタに対応している。 Free planであれば5つのWorkSpaceを持てる。 Android Stuioでいえば1つのプロジェクト=WorkSpaceになるだろう。 Free planではprivateなWorkSpaceを持つことはできないので、ソースコードは誰でも見れる状態になる。 Edit権限を与えなければ勝手に編集されることはない。 ちなみにWorkSpaceはActive Workspaceで確認できる。 どんな感じなのか気になったので、パソコン2台使ってとりあえず試してみた。 試した環境が同一LAN内にあるPCではあったことが関係している可能性はあるけれど、遅延はほぼないと思っていいだろう。 Summonなる機能があって、これを使えば他のコラボレーターを自分が編集しているファイルに瞬時に招集することが可能。 「このファイルがさー」「どれだよ?」 なんてときに活躍しそう。 とりあえず試したのはコード編集だけではあるが、他にもチャットができたりコラボレーションのための便利な機能が盛り込まれている。 ただ、ペアプロに便利とはいうものの、Floobitsはあくまでリアルタイムでのペアプロ目的に使うにとどめた方がいいだろう。 Floobitsにアップロードしたプロジェクトを、Floobitsに接続しない状態で更新→FloobitsのWorkSpaceに接続という流れになると、リモートのファイルを上書きするか、リモートのファイルでローカルを上書きするかの2択になってしまう。 Gitでバージョン管理していても、FloobitsのWorkSpace自体はGitで管理されているわけではないので、下手するとGitの履歴自体が上書きされてなかったことにされる恐れもありそう。 プロジェクトはGitで別途管理して、サブ的にFloobitsを使うという感じがいいのかもしれない。 ゼロからいきなりFloobitsのWorkSpaceにジョインして開発を進めるとおかしなことになりそう。 gitと併用してFloobitsを使う場合のFAQがあった。 https://floobits.com/help/faq 運用でカバーする必要があるっぽい。 リモート経由でペアプロするのには非常に便利だと思う。 またFloobitsはAndroidに限らず使えるというのは便利な点だろう。 セキュリティ的にどうなんだというところがクリアできるなら、普通に便利な気がする。

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となっているのだが、このキーマップ設定自体は共有してくれるものの、これが有効な状態にまでは復元してくれない。 そのため、どのキーマップを使うか、コードスタイルはどれを使うかなどは手動で直さないといけないようだ。

Android Studio2.x時代のプロジェクトを3.0環境へ更新

ストアに公開しているアプリは2018年8月までにtargetSdkVersionを26以上にする必要がある。その関係で以前にリリースしたアプリを更新しているのだが、その際に最初のハードルとなるのが古いAndroid Studioで作ったプロジェクトを現在のバージョンに更新する作業である。 最近何回も同じことをやっているので、備忘録的に書いておく。 基本的には全部Migrate to Android Plugin for Gradle 3.0.0に書いてあるので、そのとおりにやるだけである。 書いている途中でAndroid Studio 3.1が正式版になった。が、3.0から3.1への更新はそんなに大きく変更しなくても済むので、基本は3.0へのマイグレーションガイドに書いてあることに対応すればよいはず。 Gradleのバージョン更新 まず始めにGradle(Gradle wrapper)のバージョン更新を行う。Android Studio3.0は最低でもGradle4.1以上が必要。(3.1はGradle4.4以上) gradle wrapperの更新はgradle-wrapper.propertiesファイルを書き換えてgradle syncを行うだけ。 私は./gradlew wrapper --gradle-version=<Gradleのバージョン>コマンドで更新している。これで更新したらシェルスクリプトの更新もかかる場合があるので、こっちのほうがいいのかなという雰囲気で選んでいるだけだったりする。 コマンドで更新した場合、distributionUrlで指定されるgradle wrapperが4.x-bin.zipといった感じでバイナリのみのものになる。Android Studioはallにしとけと変更を促してきて、結局手書きでdistributionUrlを書き換えることになるので、普通にマイグレーションドキュメントにあるようにgradle-wrapper.propertiesを書き換えるだけでいいと思う。 ちなみに利用するgradleのバージョンだが、私の場合Twitterで見かけたGradleのリリースツイートを見て覚えてるバージョンを利用している。今だと4.6。 使えるバージョンはhttps://gradle.org/releases/で確認できる。基本的には最新使っとけばいいんじゃないだろうか。 build.gradleの更新 android gradle pluginのバージョンを更新 repositoryに`google()`を追加する(先にGradle wrapperのバージョンを上げておく必要がある) 利用しているgradle pluginのバージョン更新 プロジェクトで利用しているgradle pluginのバージョンが古い場合、原因がよくわからないエラーが多発する。例えばNo signature of method: com.android.build.gradle.internal.scope.VariantScopeImpl.getGenerateRClassTask() is applicable for argument types: () values: []とか。こういうのは利用しているgradle pluginを最新のバージョンに更新すると解消されることが多かった。 基本的にAndroid Studioが利用しているプラグインの新しいバージョンがあれば教えてくれるはず(網掛けになって新しいバージョンがあることを示唆してくれる)ので、それに従ってgradle pluginのバージョンを上げてみると解決する場合が多いだろう。 エラーメッセージで検索してもこれといった解決策が見つからないという場合には、利用しているプラグインのバージョンを上げることを試してみよう。 ライブラリプロジェクトを利用している場合 昔はライブラリプロジェクトを利用している場合、publishNonDefault trueを設定して、アプリケーションモジュールをdebugビルドするときは、ライブラリプロジェクトもdebugビルドにするなんて指定をしている人もいただろう。 この設定をしている場合、Android Studio3.xにアップデートするにあたってちょっとした手直しが必要になる。 Android Studio3.0からはライブラリモジュールのビルド設定は、利用するアプリケーションモジュールのものと同じものが利用されるようになった。appモジュールでdebugビルドを選んだら、自動的に依存しているライブラリモジュールもdebugビルドでビルドされる。 そのため以下の手直しが必要。 ライブラリモジュール publishNonDefault trueの記述を削除する。 アプリケーションモジュール 例えば以下のように記述していたとする。 debugCompile project(path: ":library", configuration: "debug") releaseCompile project(path: ":library", configuration: "release") この場合、この2行は不要になるので削除。その後あらためてimplementation project(":library")とライブラリモジュールへの依存を記述する。 buildTypeを増やしている場合 追加でbuildTypeに手を加えている場合(デフォルトのdebugとrelease以外に定義している場合)、増やしたbuildTypeの定義にmatchingFallbacksという行を追加してやる必要がある。 これはそのbuildTypeが使われるときに、それが存在しないライブラリプロジェクトなどがどのbuildTypeを使えばいいかを指定するものだ。 Android Wearアプリを利用しているプロジェクト ライブラリモジュールと同様の問題と変更が行われている。publishNonDefault trueが要らなくなって、debugWearApp ...という記述群がwearApp(":wear")の1行で済むようになった。 プロダクトフレーバーを利用している場合 新しくflavorDimensionsを最低1つは定義しないといけなくなった。 productFlavorは何らかの基準で使い分けているはずなので、その基準を定義すれば良い。例えばhttps://github.com/gen0083/FilteredHatebuこのプロジェクトは、ネットワークのレスポンスという観点からmockとprodというプロダクトフレーバーを定義している。 ネットワークの観点で切り分けているので、flavorDimensions "network"という感じで定義してやる。 後はproductFlavorの定義の部分で、どのdimensionに属する定義なのかを指定してやればいい。flavorDimensionsが1つしかないのであれば省略可能である。 私は最初勘違いしていたのだが、これは決して各フレーバーごとに異なるdimensionを割り当てなければならないということではない。このプロジェクトでは最初mockにtest、prodにdefaultというdimensionを割り当てたのだが、そうするとプロダクトフレーバーはmockProdDebugという形になってしまい、mockとprodを切り替えられなくなってしまった。切り替えて使うものについては、同じdimensionを割り当てないといけない。 apt → annotationProcessorへの置き換え これは確かmustだったような気がする。(気がするというのは、最近更新したプロジェクトの中にはaptを使っているものがなかったので) 古いプロジェクトだとgradle pluginを使ってアノテーションによるコード生成ライブラリを使っていたと思うが、その機能は公式に取り込まれているので、gradle pluginの削除とaptをannotationProcessorに置き換えてやる。
Read full post gblog_arrow_right

flutterやるならぜひ登録しておきたいLive Template

Flutterを触り始めたのだが、とにかくWidgetのレイアウト変更がツライと感じていた。 AndroidでいうところのViewのレイアウトがコードでゴリゴリ書いていく感じになっているので、インデントが深くなってツライ。Widgetの考え方もAndroidのViewとはちょっと違う(レイアウトに関する設定はレイアウト情報を持つWidgetでくるむとか) ゼロから作る分にはまだいいのだが、一度作ったレイアウトに対して、「このTextにmargin付け加えたい」となったときがツライ。シンプルなレイアウトならまだいいが、Widgetが何個も登場したり、何回層もネストされてたりすると正直触りたくない。 例えばこんな感じ。 @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( title: new Text("FriendlyChat"), ), body: new Column( children: <Widget>[ new Flexible( child: new ListView.builder( padding: const EdgeInsets.all(8.0), reverse: true, itemBuilder: (_, index) => _messages[index], itemCount: _messages.length, ), ), new Divider(height: 1.0,), new Container( decoration: new BoxDecoration( color: Theme.of(context).cardColor, ), child: new Text("hoge"), ), ], ), ); } これはまだかわいいものだが、それでもめんどうくさい。 そこでLive Templateを追加して、IntelliJのSurrond With機能を使って簡単にWidgetを囲えるようにしてみた。Flutterのチュートリアルを試したりするのに活躍するのでかなり捗ると思う。 Live Templateを定義 Preference > Editor > Live Templateが定義場所。 定義する場所は別にどこでもいいのだろうけれど、Flutterに関することなのでFlutterのところに追加した。 new Column( children: <Widget>[ $SELECTION$ ] ), Dartファイルに適用されるように指定して、Reformat according to styleにチェックも入れておく。 new Container( child: $SELECTION$ ), childを1つしか取らないWidgetでラップする場合に使うやつもついでに追加。使っているのがColumnとContainerであることに特に意味はない。まあそこは必要に応じてクラス名を書き換えればいいだろうから気にしない。 Live Templateを定義したら、後は囲いたいWidgetを選択した状態で、Surround with機能を呼び出し(私の環境だとcmd+opt+t)、定義したLive Templateを適用すればよい。楽ちん。 Live Templateは初めて活用したので、もっとこうした方がいいよというのがあったら教えて欲しい。 追記: 記事を書き終わった後で、そもそも標準でWidgetをラップする機能が存在していることを知った。ラップしたいWidgetのクラス名にカーソルをあわせた状態で、Intention Actions(Macならopt+enterで出るやつ)を使うとWidgetを別のWidgetでラップすることができる。わざわざLive Templateを追加する必要はなかった・・・。

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

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の対象外にすることでしのげる。 ともあれ、個人的にとても便利なプラグインだと思う。あまりに感動して作者にお礼のツイートを送ってしまうほど、ドンピシャなプラグインだった。 少し幸せになる技術というスライドで紹介されていたが、私は少しどころではなくかなり幸せになれた。ありがたい。

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

タイトルが分かりにくいんですが、こちらの画像をご覧ください。 画像の例ではアプリのパッケージ名が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に変更すると普段通りの表示になりました。 DataBindingを使っている人のみ影響を受けるみたいです。 最近はfindViewByIdを使わなくて済むからくらいの軽い理由で、DataBindingを多用しているので早く直ってほしいです。 まあProjectウィンドウが見づらくてなんか気持ち悪いってだけなんですけどね。 Android Studio 2.2.1で直ったみたいです。

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

layout.xmlを開いた際に、デフォルトではDesignタブで開かれると思います。これをTextに変更する方法です。 Android Studio 2.1まではレイアウトのPreview画面に歯車アイコンがあって、Prefer XML EditorにチェックをつければOKでしたが、Android Studio 2.2のPreview画面にはそのようなものが見当たりません。 Android Studio 2.2からは、設定画面から変更するようです。 Preference > Editor > Layout Editorで設定できます。