2012年9月13日木曜日

git pull 時の rebase オプションのススメ


今日は、Git で複数人作業を行う際に共有リポジトリから pull する際の rebase オプションの必要性について検討してみました。

タイトルで結果は想像つくような気がしますが、順を追ってみましょう。

  1. git pull でやってること
  2. merge と rebase
  3. git pull と git pull --rebase
  4. まとめ



  1. git pull でやってること

git pull コマンドは、fetch, merge をまとめて実行しています。
つまり、リモートブランチの最新のコミット情報をローカルトラッキングブランチへ持ってきて(fetch)、持ってきた最新のコミット情報とローカルブランチをマージ(merge)します。

参考:3.5 Git のブランチ機能 - リモートブランチ


  2. merge と rebase

ブランチを統合するには、マージの他にリベースがあります。

mergeでは、ブランチAコミット1から派生したブランチA2コミット2とブランチA3コミット3を統合した場合、統合結果のコミットオブジェクト4が統合先のブランチ上に作成されます。

これに対し、リベースでは、その名のとおり、基点を移動するかのような挙動をとります。
つまり、コミット3の基点がコミット1ではなく、コミット2とし、コミット2に対してコミット3の差分を適用します。

参考:3.6 Git のブランチ機能 - リベース


  3. git pull と git pull --rebase

共有リポジトリから資産を取得するのに通常は、git pull を利用しますが、このコマンドにはオプションとして --rebase オプションが用意されています。

rebase オプションをつけた場合は、fetch後の挙動がmergeではなく、rebaseとなります。

以下、それぞれの挙動と、それによるコミット履歴の差を確認してみました。

環境

確認用に以下のシンプルな構成で分散環境を構築します。
  • リモートリポジトリ:gitPullTest.git
  • ローカルリポジトリ(Alice):gitPullAlice
  • ローカルリポジトリ(Bob):gitPullBob
  • バージョン管理対象:gitPullTest.txt

以下の動作検証を行います。
  • リポジトリは全てローカルマシン上に作成する。
  • Alice役とBob役がそれぞれ独自の編集を行う。
  • Aliceが先にプッシュし、Bobは、git pull、git pull --rebase で変更を取り込む。
  • 例を単純にするため、masterブランチのみとする(git flowは利用しない)

準備(共有リポジトリ、Alice, Bob リポジトリ作成と内容の同期)


git pull(マージによるコミット)


git pull --rebase(リベース)


結果(コミット履歴)







コミットログ最下部は、初期登録時のコミット
下部2番目から4番目までが、git pull によるコミット履歴(3コミット)
下部5番目から6番目までが、git pull --rebase によるコミット履歴(2コミット)


  4. まとめ

このように、マージの場合、マージコミット分が履歴に残るのに対し、リベースでは(例えコンフリクトが発生したとしても)コミット履歴は直線的に保たれます。
このことから、共有リポジトリを介した頻繁に資産のやり取りが発生するような開発ではgit pull 時のrebaseオプションは以下のように使い分けるべきだと考えられます。

  • 通常の資産共有の一環としてのgit pull では、リベースを用いる。
  • 統合した事実を残しておくべき場合(リリースブランチへの機能追加など)はマージを用いる。


やはり、通常開発時はリベースを用いることのメリットのほうが多いと思います。
(資産のやり取りごとに不要なマージコミットができるのは避けたいはず)
また、マージを用いるべき箇所に関してはgit-flowなどの運用フローを採用することで意識しないようにするほうが確実です。

git-flowに関しては、以下を参考にしてください。
ゼロからわかるgit-flow

Gitに関しては、色々な運用方法があるので、他にもよいプラクティスがあれば教えてもらえればうれしいです。

ではでは。

2012年8月12日日曜日

エンジニアとしてのアイアンマンがステキな件

DVDでアイアンマンを見た。


















主人公トニースタークが、捕虜になり脱出のためにリアクターとスーツを開発、
その後、人工知能を搭載した試作機を経て実用機を完成させ、陰謀に立ち向かうストーリー。


ストーリの感想はまた別の機会として(話や役者さんも個人的には満足でした)
スーツの開発を進めていく、エンジニアとしてのアイアンマンがステキだった。

捕虜の環境で開発した最初のスーツは全て手作業。
組み立ても、装着も、ウェポン発動のギミックも全て。

でもスーツを洗練していくのにあわせて、組み立ても装着も自動化されていく。
組み立ては設計をインプットして5時間後に塗装済みのものが用意され、
複雑な装着もロボットアームが的確にこなしていく。

制御の複雑化には人工知能で対応。
音声制御で、主人公は自分の動きに専念する。



プロダクトの洗練において周辺環境含め、常に自動化、省力化を念頭におく。
これ大事だと思う。
そうでなければ、いつまでたったって本質に注力することなんてできない。

それはトニースタークのような天才的な頭脳でなくても、やり方として使っていけることで、
システム開発でもテスト自動化や継続的デリバリーを使って、本質に注力していけたらなと思うのです。

以上、そんなことを考えさせられたアイアンマンでした。



着陸時の姿勢、かわいいですよね、アイアンマンw

2012年8月11日土曜日

SwimmyStudy #9 Jenkins実践入門 vol.3 に行ってきました

8/8(水)にSwimmyStudy #9 Jenkins実践入門 vol.3 に行ってきました。
SwimmyStudy #9 Jenkins実践入門 vol.3

書籍「Jenkins実践入門 ~ ビルド・テスト・デプロイを自動化する技術」をもとにした勉強会です。
現在、初級者向け、初中級者向けのグループに分かれてそれぞれが書籍ベース、実践ベースで勉強会を行っています。

自分はAndroid開発で利用経験があるので初中級者向けに参加しています。
以下、主に初中級者向けグループに関する参加レポートです。

  1. 初中級者向けグループ(JFK)概要
  2. 初中級者向けグループ(JFK)実施内容
  3. 所感


  1. 初中級者向けグループ(JFK)概要

  • Jenkins経験者が中心となって、Jenkinsとバージョン管理、バグ管理のシステムと組み合わせた効果的な開発環境とルールづくりを模索していく。
  • バージョン管理には、Gitとgit-flow、バグ管理にはRedmineを想定しており、複数人の開発者と管理者による疑似プロジェクトとして上記環境構築とルールづくりを検討することとする。
  • なお、プロジェクト資産は、CakePHPによるサンプルブログシステムを利用する。

今回は、JFKでの第一回ということで、上記疑似プロジェクトに基づき、バージョン管理システムとJenkins連携部分を検討しました。


  2. 初中級者向けグループ(JFK)実施内容

LT

バージョン管理システムとしてGitとgit-flowを採用するにあたり、以下のLTを行い、前提知識を合わせました。
ゼロからわかるgit-flow

Git, git-flow実践

サンプルシステムを用いながら、git-flowのフィーチャー、リリース作業を複数人で実践しました。


課題

  • プロジェクトで用いるサンプルブログシステムが主にDB周りで起動できなかったため、急遽、簡易的なテキストファイルを対象としたバージョン管理を行うことになった。
    [対策]:次回、DBをMySQLからSQLiteに変更して環境依存部分を極力減らす。
  • git-flowまわりの経験不足もあり、複数人でのブランチのマージ、コミットで時間を要してしまった。
    [対策]:git-flowまわりのノウハウを増やす(参考:Git-Flow-Example
    [対策]:複数人で行う場合の構成を再度検討する必要がある。(後述)


Jenkins連携の検討

前述の課題を踏まえてJenkins連携の検討を行いました。

  • origin/developへ各開発者が直接pushを行うと別開発者とのマージが頻発したため、各開発者ごとにoriginとなるリモートリポジトリを設け、中央originへの集約は管理者が行う。
  • git-flowのリリースブランチの開始、終了はmasterへの変更が発生するため、管理者が行う。
  • 中央originのdevelopをJenkinsと連動させ、結合テストを定期実行させる。
  • 中央originのmasterをJenkinsと連動させることを検討したが、masterへのコミット後のテストとなるため、バグがあった場合にmasterブランチを汚してしまう。
    回避策としてgit-flowのリリースブランチに対して受け入れテストを実行させる。
    テスト完了後、必要に応じてJenkins側からリリースブランチのfinishを行い、masterへのコミットを行う運用とする。
  • JFKではリモートリポジトリ間としてGit、リポジトリ間のやりとりにPullRequestを用いる。

以下、構成イメージを示す。




















次回

次回は、上記構成を実際に検証してみます。

以下の事前準備を行っておけるとベターです。
  1. GitHubのアカウント
  2. 自端末へのGit, git-flowが動作する環境。
  3. (できれば)サンプルブログアプリ(CakePHP SQLite)の動く環境。

  3. 所感

Jenkinsとの連携までは今回行けませんでしたが、事前準備としては課題等も見え有意義な会だったと思います。
やはり複数人で実際に行うことで見えてくる課題もあり、それらを(業務のタイムリミット関係なしに)検討することができるのが非常によいです。

あっという間の2時間半でした。待ちきれないので次回からスパンを短めにとることになりましたw

次回は8/29(水)です。
SwimmyStudy #10 Jenkins実践入門 vol.4 

Jenkins関連のLT大会もあるので、興味ある方はぜひ!

2012年8月9日木曜日

Android Night in Fukuoka vol.28 に行ってきました。

8/6(月)にAndroid Night in Fukuoka vol.28 に行ってきました。
Android Night in Fukuoka vol.28

今回は、参加者20名ほど。会場のAIP Cafe がものすごい暑くなりながらのNightとなりました。
内容を一応まとめておきます。
  1. 宣伝
  2. LT
  3. 所感

  1. 宣伝

今回は、以下の勉強会について宣伝がありました。

  • 日程調整中 初心者勉強会
  • 8/25(土)Android ドM(次回ペアプロ)
  • 毎週月曜日 輪講する会(Andorid高速化プログラミングの輪講)


  2. LT


@kenz_firespeedさん

Android 4.1(JellyBeans)の新機能紹介を行っていただきました。

報告内容はご本人のブログにてまとめられています。
Android Nightに参加してきました

4.1では様々な改良が加えられており、性能面でもかなり改善されているみたいなので楽しみです。
個人的には通知エリアの機能拡張が気になったので別途調べてブログにまとめてみたいなと思っています。

詳細は8/18 GDG九州in宮崎にて行うとのことですので、興味ある方は参加してみてはいかがでしょうか。


@monochromegane

自分からは、以前公開した状態保存のライブラリBundleSaver改めStateSaverの紹介を行ってきました。

振る舞いのよいAndroidアプリのために。BundleSaver。
続・振る舞いのよいAndroidアプリのために。StateSaver。
GitHub / monochromegane / BundleSaver 


GitHubのPullRequestをお待ちしておりまーす。


@yuutoさん

支部長からは、Androidで使える軽量なライブラリ(AQuery)の紹介LTがありました。

AQuery
AndroidのUI操作にまつわる各種記述を単純にするためのライブラリ。
IDを指定してビューを取得、値の設定、リスナー設定といった記述をメソッドチェーンで書くことができます。
その他、非同期通信に関しても簡潔に記載できるので、開発工数削減することができそうです。

リスナー設定等、アノテーションを利用しているので性能面は注意が必要とのこと。
ライセンスはApache2.0でした。

いつも楽しげなライブラリを紹介してくれる支部長さんに感謝。
これもまた今度使ってみたいと思います。


@kenz_firespeedさん

本日2度目のLTです。
福岡と世界をつなぐ「Hello World」プロジェクトについての構想を語っていただきました。

こちらも報告内容がご本人のブログにてまとめられています。
Android Nightに参加してきました


昨年、私もアメリカ行きましたが、やはり英語の必要性を痛感しました。
こういったプロジェクトを通じて世界とつながる機会を持っていきたいですね。




  3. 所感


固定の顔ぶれも多いですが、毎回、新しい方も参加しています。
最近感じるのは、業務でAndroidを触ったのがきっかけで参加しているかた(Web界隈の方)が増えてきていることでしょうか。それだけ世間に浸透してきたという証拠なのでうれしいことです。

趣味として個人で触っている方が減ってきた気もするので、次回のLTは、個人作成のアプリでも紹介してみようかなと思っているところです。

毎回所感に書いてますが、色んな人に知り合えるので、情報交換、収集の場にちょうど良い会です。
ここからネットワークが広がることが多いので興味のあるかたは是非参加してみてください。

-----------------------------
次回、Android Night in Fukuoka vol.29 は、9月初旬のはずです。
興味湧いた方は、お気軽にどうぞ!

ではでは。

2012年8月6日月曜日

SQLiteの高速化:クエリのトランザクションは本当に有効か測定してみた

書籍「Androidアプリ高速化プログラミング」の輪講会に参加しています。

Androidアプリ高速化プログラミング















先日の第1章の輪読の際に、クエリの高速化の項で気になった点があったので検証を行ってみました。

  1. 書籍の主張:クエリの高速化
  2. 書籍の主張:推論
  3. 性能測定してみる(条件など)
  4. 性能測定してみた
  5. まとめ(?)
  6. 参考(計測に利用したクラス)


  1. 書籍の主張:クエリの高速化

気になった記述は、以下の箇所です。

第1章 Javaコードの最適化 (P.36) 1.7.3 クエリ
複数のトランザクションを使う場合、iterateBothColumns()は61ミリ秒かかるが、iterateFirstColumn()は23ミリ秒で実行される。すべての行を1つのトランザクションにまとめると、すべての行の処理にかかる時間はさらに短くなる。iterateBothColumns()は11ミリ秒かかるが、iterateFirstColumn()は7ミリ秒で実行される。
iterateXXColumn()は、SQLiteデータベースに対してクエリを発行するメソッドであり、それぞれ、カラムを指定しない場合、する場合で処理速度に差が発生するという内容なのですが、それに対する説明で、「すべての行を1つのトランザクションにまとめると」という記載があり、性能がさらに改善する上記の記述があります。


  2. 書籍の主張:推論

上記、書籍の主張ですが、輪読会でも全レコードを一括で取得するクエリに対して、「すべての行を1つのトランザクションにまとめると」というのがイメージがつかないよねーという話になりました。

推論1:
一回のクエリでもトランザクションを制御することで処理速度が向上する(そんなバカな)


推論2:
Selectクエリでもトランザクションが開始、終了しており、複数回のクエリをひとつのトランザクションにまとめることで処理速度が向上する。

以下、各推論に対して処理速度の計測を行ってみました。


  3. 性能測定してみる(条件など)

以下の条件でクエリの性能測定を行ってみました。

環境

Android:2.3.3
機種:エミュレータ


テーブル構造

テーブル名:cheese ※世界のチーズ一覧を格納します。
レコード数:650件

カラム名
idINTEGER ※インデックスカラム
nameTEXT
originTEXT


測定パターン

いずれも全件に対するクエリを発行。
取得対象のカラムと、トランザクション制御の違いを検証します。

取得方法トランザクション制御
全レコード(一括)AutoCommitあり
全レコード(一括)AutoCommitなし
各レコードAutoCommitあり
各レコードAutoComitなし


  4. 性能測定してみた

全レコードを一括で取得















全レコードを一括で取得(Where句なしのSelect文)では、トランザクション制御を手動で行った場合のほうが、処理時間が長くなってしまいました。

いずれもクエリ回数は一回であるため、トランザクションを操作するオーバヘッドが差につながったのではないかと推測されます。

推論1は、あえなく崩れました。
それでは、書籍のトランザクションをまとめて扱うとはどういうことなのでしょうか。
おそらく、下記のパターン(推論2)のことを言っているのではないでしょうか。


全レコードを個別に取得















全レコードを個別に取得(Where句にIDを指定し、レコード数だけループで全件取得)では、トランザクション制御をループの前後のみで行った場合のほうが処理時間が短くなりました。

このことからSelect文を複数発行する場合、ひとつのトランザクションとして扱ってあげるほうが性能の向上が見込めることがわかります。

ただし、処理時間自体は、クエリの回数が増えているため、一括で取得する場合に比べて大幅に増加してしまっています。
書籍のような7ミリ秒での実行からは離れてしまいました。


  5. まとめ(?)

複数回のクエリに対してトランザクションをまとめることが処理性能に有効だということは確認できました。

ただし、検証の結果、ますます書籍の言っていることがわからなくなってしまうという情けない結果になってしまいました。とほほ…。

書籍でいうような処理速度改善の方法があればアプリに適用したいのですが…。

検証結果、書籍の内容について、アドバイス等いただければ幸いです。


  6. 参考(計測に利用したクラス)

性能測定で利用したクラスです。

これらのTaskを別途準備した計測用のクラスに渡して計測を行いました。

こういう計測を行ったほうが効果的だよというのがあればご指摘もらえればと思います。


以上です。

2012年7月24日火曜日

WindowsでGit共有リポジトリをさくっと構築

プロジェクトのGitサーバをWindows機で構築する機会があったので、簡単に手順をまとめておきます。

通常はLinuxで構築することが多いと思いますが、今回はプロジェクトの制約でWindows機を使うことになりました。

ここで紹介する手順は、小規模な社内環境を想定していますので認証、セキュリティは考慮していませんが、「最小の構成でよいから手軽に構築したい」といった場面でのご参考にしていただければと思います。

  1. 環境
  2. インストール
  3. 共有リポジトリの作成
  4. 外部接続の設定
  5. 接続確認


  1. 環境

今回、構築する環境は以下のとおりです。

  • 共有GitリポジトリはWindows機上に構築
  • GitにはmsysGitを用いる
  • 共有Gitリポジトリとの接続はgitプロトコルを用いる
  • クライアント側のGit環境は構築済みとする

接続にgitプロトコルを用いることで、SSH鍵等の準備する手順を削減しています。


  2. インストール

以下のサイトからWindows用のGit「msysGit」をダウンロードします。
msysGit

以下のようなexeファイルが対象となりますので、最新版をダウンロードしてください。
Git-1.7.XX-previewXXXXXXXX.exe

※1.7.10未満のバージョンでは、日本語ファイル名が正しく扱えないとのことなので、
1.7.10以上のものを選ぶようにしてください。

ダウンロードしたexeを実行し、インストールを行います。
インストール時に聞かれる選択肢に関しては、特に悩むところはないと思います。


  3. 共有リポジトリの作成

共有リポジトリのベース作成

今後、共有リポジトリを格納していくベースとなるフォルダを決め、該当フォルダを作成します。
ここで決めたベースを後述するGitDaemonに設定しておくことで、クライアント側からのアクセス時にベース以降を指定できるので便利になります。
(ここでは、D:¥Git¥reposをベースとします。)


共有リポジトリのフォルダ作成

先ほど作成したベース配下に、共有リポジトリとなるフォルダを作成します。
(ここでは、sample.gitを共有リポジトリとなるフォルダとします。)


共有リポジトリの初期化

作成したsample.gitフォルダを右クリック->Git Bashを選択し、以下のコマンドを入力します。
sample.gitフォルダ配下に各種ファイルが生成されたことを確認します。


  4. 外部接続の設定

外部から共有リポジトリに接続するための設定を行います。

GitDaemonの起動

gitプロトコルを用いて外部からの接続を行う際に必要となるGitDaemonサービスを起動します。

GitBashから以下のコマンドを実行します。

※都度、実行するのは煩わしいので、以下のようなバッチをスタートアップに登録するのがよいと思われます。
GitHub:Gist / RunGitDaemon.bat
各定義は、お使いの環境にあわせて変更してください。

Windowsファイヤーウォールの設定

GitDaemonが通信に利用するポートであるTCP/9418を、Windowsファイヤーウォールで受信可能にします。



  5. 接続確認

クライアント側で、以下のコマンドを実行し、接続できることを確認してください。



--------------------
以上です、Windows Git 共有リポジトリ環境の構築を行う際の参考になれば幸いです。

2012年7月9日月曜日

続・振る舞いのよいAndroidアプリのために。StateSaver。

以前公開したBundleへの状態保存を自動化するBundleSaverをバージョンアップしました。
GitHub / monochromegane / BundleSaver



  1. BundleSaverから "StateSaver" へ
  2. StateSaverの使い方

  1. BundleSaverから "StateSaver" へ

前バージョンのBundleSaverの考え方、利用手順はこちらをご覧ください。
振る舞いのよいAndroidアプリのために。BundleSaver。

前バージョンでは、状態の保存先として、Bundleを対象としていました。
しかし、Bundleへ保存された状態は、アプリが生存する間しか保存されません。
アプリ終了後も状態を利用するには、何らかの手段を用いて永続化する必要があります。

今回、BundleSaverは「状態保存」の責務を果たすため、状態の永続化もサポートするように機能拡張を行いました。
また、それに伴い、プロダクト名をBundleSaverから "StateSaver" へ変更します。

なお、永続化の手法としては、Preferenceを採用しました。


  2. StateSaverの使い方

BundleSaverからStateSaverになるに伴い、利用するメソッドやアノテーションが変更になっていますが、基本的な利用手順は今までと同様です。
(念のため旧メソッド関連も非推奨メソッドとして残しています。)

変数の宣言時に、アノテーションで状態保存の対象であることを記載してください。
このとき、保存先がBundleかPreferenceかで指定するアノテーションを切り替えます。
なお、両方に保存したい場合、アノテーションを2つとも指定すればよいです。




対象となる型は、Bundle、Preferenceに格納できるもの + αです。
プリミティブ型、ラッパーオブジェクト、Bundle, Parcelable, Serializable などが格納できます。
詳しくはGitHub上のREADMEをご覧ください。


対象となるインスタンス変数にアノテーションをつけるだけで、保存/復元処理はStateSaverを呼ぶだけなので、使いやすくなるんじゃないかと思います。
また永続化対応によって簡易な設定等の保存/復元にも対応したので、実装がシンプルになるメリットもあると思います。

状態の保存/復元は地味ですが、ユーザ側にとって振る舞いのよいアプリケーションをつくるのに重要な処理なので、ぜひ使ってみてください。

-------------------------
ここはこうした方がよいよとかご指摘ありましたら、教えてもらえれば幸いです。
GitHubのPullRequestもお待ちしております。

ではでは。

2012年7月6日金曜日

SwimmyStudy #8 Jenkins実践入門 vol.2 に行ってきました

7/4(水)にSwimmyStudy #8 Jenkins実践入門 vol.2 に行ってきました。
SwimmyStudy #8 Jenkins実践入門 vol.2


書籍「Jenkins実践入門 ~ ビルド・テスト・デプロイを自動化する技術」をもとにした勉強会ですが、今回から初級と、初中級を分けて勉強会を進めることとなったとのことで、それぞれのグループで今後どのように進めていくかを打ち合わせることがメインの会となりました。

内容について、まとめておきます。

  1. 会の概要
  2. Jenkinsデモ
  3. 各グループの今後の方針
  4. 宣伝
  5. 所感

  1. 会の概要

参加者の構成

もともとSwimmyStudyが、「悩めるウェブプログラマーのためのワークショップ」とのことなので、PHPerが多かったです。
Jenkinsという切り口のため、自分のような他分野のメンバが入るかたちになりましたが、快く受け入れてくれてとてもステキな会だなあと思いました。


取り組み内容

Jenkins実践入門ということで、書籍「Jenkins実践入門」をもとにハンズオン形式で環境構築をみんなでやっていく会です。
ただし、今回から一部経験者に関しては、グループを分けて進めることになりました。(同じ日、同じ場所でやります)
各グループの進め方については後述します。


タイムスケジュール

今回のタイムスケジュールは以下のとおりでした。
  • 19:30 – 20:30     RackhubでCakePHPのプロジェクトをJenkinsで動かしてみるデモ
  • 20:30 – 22:00     グループ別勉強会(今後の方向性打ち合わせ)


  2. Jenkinsデモ

@ootatterさんによるRackhubでCakePHPのプロジェクトをJenkinsで動かしてみるデモ。

残念ながら、回線トラブルでRackhubにつながらず…。
ローカル環境でCakePHPのプロジェクトをJenkinsで動かしながら、各参加者からの質問に答えながら進みました。
プロジェクトがPHPでもAndorid/Javaのときと同じような構成で組めることがわかってJenkinsプラグインの豊富さに感心しました。

質疑応答の時間では、主にプロジェクトのテスト技法についてと、Jenkinsをどう使っていくのが有用なのかについて議論しました。
また、この議論内容を発展させて、各グループにて今後の方針を決めていくかたちになりました。


  3. 各グループの今後の方向性

初級グループ

ウェブプログラマーの方々が中心となって、Jenkinsの使い方を習得していくグループです。
開発手法、テスト手法、PHP動向について熱く議論を交わされていたのが印象的でした。

以下、今後の方針についてです。

  • PHPerの方が中心となって、従来どおり書籍を参考に環境を構築していく。
  • 書籍がJavaプロジェクトをもとに記載されている部分をPHPプロジェクトで進めることとする。
  • PHPプロジェクトでは、フレームワークとしてFuelPHPを利用することで最新技術習得もあわせて行っていきたい。
  • 随時、下記グループと連携を取り、手法の向上を行っていく。


初中級グループ

自分は、Androidのテスト自動化を行う際にJenkinsも合わせて利用していたのでこちらのグループに参加させてもらいました。

以下、今後の方針についてです。

  • Jenkins経験者が中心となって、Jenkinsとバージョン管理、バグ管理のシステムと組み合わせた効果的な開発環境とルールづくりを模索していく。
  • バージョン管理には、Gitとgit-flow、バグ管理にはRedmineを想定しており、複数人の開発者と管理者による疑似プロジェクトとして上記環境構築とルールづくりを検討することとする。
  • なお、プロジェクト資産は、前述のデモで利用したCakePHPによるブログシステムを利用する。

以下、次回の方針についてです。

  • 次回は、共有バージョン管理システムとJenkinsの連携部分の構築を行う。
  • 各メンバは、事前にGit、Jenkins環境とCakePHPの動作環境まで整えておくことが望ましい。

次回、自分からgit-flowについてのLTを最初に行います。
初級グループのかたも興味があれば聞いてあげてください。

ちなみにグループ名は、Jenkins Flow (仮) 、略してJFKです。
かっこいい!


  4. 宣伝

7/29(日)Jenkins ユーザ・カンファレンス 2012 東京

東京にて開催。
1300人!会場で、XFDについてのセッション内で、今回勉強会参加の@gokingさんがXFDについて講演するとのこと。


7/31(火)Jenkinsの生みの親、川口耕介さんによる福岡イベント

上記ユーザカンファレンスにあわせて全国行脚するとのことで、福岡では、きしださんと
勉強会チックなものを開催する予定みたいです。
内容はまだ決まってないとのこと、別途アナウンスがあると思います。


7/20(金)Fukuoka.php

今回の勉強会を主催されている、@mawatarinさんが最近イチオシのFuelPHPの紹介があるとのことです。
なお、日程は現時点での仮日程とのことなので、別途ATND等をご参照ください。


  5. 所感

PHPerではない自分が参加していたので、進め方について色々@mawatarinさんには配慮していただいて申し訳なかったかなと思ってますが、Jenkinsの経験があるという部分でJFKチームで色々つっこんだ議論を進めて、会にフィードバックしていければなと思います。

JFKは、普段のプロジェクトでは時間の都合上できないような試行錯誤を繰り返していけるよい機会になりそうでいまから楽しみです。

次回は、8/8(水)です。うーん、待ちきれないかも。



2012年7月4日水曜日

Android Night in Fukuoka vol.27 に行ってきました

7/2(月)にAndroid Night in Fukuoka vol.27 に行ってきました。
Android Night in Fukuoka vol.27

前日のAndroid Hackathon の疲れも癒えきらぬままのNight参加となりました。
参加者、LTもいつもよりは少なかったですが、一応まとめておきます。
  1. LT
  2. 宣伝
  3. 所感

  1. LT

今回のLTは自分と支部長がそれぞれ行いました。
両者ともに前日のHackathonが効いて資料が多少ライトな感じとなってしまいました。

@monochromegane

自分からは、ブログエントリをもとに以下の二本をLTさせてもらいました。
ショートカットキーで開発効率化(Mac/Eclipse)
AndroidのSparseArrayは本当に速いのか測定してみた

とくにショートカット入門は、自分向けのまとめでもありますが、今後の福岡支部初級コース勉強会で使ってもらえればと思います。


@yuutoさん

支部長からは、Androidで使える軽量O/Rマッパの紹介LTがありました。

軽量O/Rマッパ - OrmLite
軽量、複雑さの回避、オーバーヘッドが少なくAndroidでも使用可能とのこと

JOINも可能なはず。
サイズは150kb以下なので、アプリへの組み込みも気にならないレベル。

このライブラリはなかなかよさそうなので、今度使ってみたいと思います。


  2. 宣伝

今回は、以下の勉強会について宣伝がありました。

  • 7/7(土)やさしいAndroid勉強会 vol.1 in しぶちょー宅
  • 7/8(日)Google I/O 報告会
  • 7/16(月)輪講する会(Andorid高速化プログラミングの輪講開始)


  3. 所感

固定の顔ぶれも多いですが、毎回、大学生や、海外の方など新しい方も参加しています。
色んな人に知り合えるので、情報交換、収集の場にちょうど良い会だなあと毎回思っています。
色々ネットワークを広げていきたいですね。
いわゆるブロガー名刺をつくりたい今日この頃です。


-----------------------------
次回、Android Night in Fukuoka vol.28 は、8/6(月)です。
興味湧いた方は、お気軽にどうぞ!

ではでは。

Android Hackathon in Fukuoka に参加してきました

7/1(日)に開催されたAndroid Hackathon in Fukuoka に参加してきました。
Android Hackathon in Fukuoka

会の内容を簡単にまとめておこうと思います。
  1. 今回のHackathon概要
  2. 参加者のアプリ紹介
  3. 所感
  4. 反省等

  1. 今回のHackathon概要

今回の参加者は10名程度で、ほぼ個人ごとにアプリを開発、自分と支部長(@yuutoさん)だけがチーム開発という体制になりました。

タイムスケジュールは以下のとおりで、丸一日使っての開発となりました。
(ただし参加者の半分ぐらいは午後から参加でした)

時間内容
10:00~11:00自己紹介・テーマ決め
11:00~19:00もくもくコーディング
19:00~20:00お披露目

また、今回はテーマを特に設けず個々でアプリを決めるかたちを取りましたが、個々が得意分野を進めることとなったので、アプリ、ウィジェット、フィジカル、ゲーム、お下品etc... と何でもありのHackathonになりました。


  2. 参加者のアプリ紹介

各参加者が作成したアプリを簡単に紹介しておきます。


@daichan4649さん

ウィジェットアプリ
直近の予定まであと何日か通知するカレンダーウィジェット
ローカルのカレンダー情報をContentResolver経由で取得して、ウィジェットに表示


@eryngii_moriさん

HTML5で画像を取得、WebSocket経由で画像をアップロードするアプリ


@treby006さん

Android BEAM するアプリ
NDEFデータのやりとりを行う


@juju_suuさん

フルカラーLEDで動画再生
動画をBitmapとmp3に事前に展開して、ImageView内で画像切替


@himitusentai_haさん

九州電力でんき予報
計画停電が始まったときを知るアプリ
九州電力HPからCSVを取得して、電気利用率をグラフで表示
グラフにはachartengineを使用


@sabasabamanさん

Arduinoと電力センサーの連携
クラウド経由で電力測定を試す


@shikajiroさん

ゆっくりと会話できるアプリ
aquestalkによる音声の発信
会話は、SpeechRecognizerで音声認識

着信の電話番号をもとに名前を検索、表示するアプリ
ホットペッパーのAPIから店の名前を取得

(@shikajiroさんに書けーと言われたので追記)
ちなみにこのアプリ、匿名インナークラス連打でインデントをあえて劇深にされてました。
こういう状態を覇王翔吼拳というそうです。ほほう。
 

クロキリユさん

書籍を参考に横スクロールアクションアプリを作成。
時間切れにて画面出せず…


チームうんこ(@yuutoさん、@monochromegane)

マキグソシミュレータ
支部長のアプリ解説を転載します。
今回はマキグソシミュレータを作った。スタートボタンを押すとカウントダウンが始まるのでその間にズボンにケツポケットにスマフォを入れてスタンバイ。スタートと同時にきれいにマキグソを巻けるようにケツを回転させ、加速度センサ等からきれいに巻けたかどうかを判定し、結果を出すアプリ。

いやんお下品。


気になる投票結果は...

  • @shikajiroさん 4票
  • @juju_suuさん        3票
  • @treby006さん 1票
  • @himitusentai_haさん    1票
  • チームうんこ            1票

  3. 所感

福岡支部の特徴なのか、フィジカル系アプリの割合が多く、最後のお披露目はかなり盛り上がったと思います。
個人的にはペアプロを通して色々得るものがあり、スキル向上の面でも参加してよかった会でした。
今後も、ドMな会をやりたいというステキなメンバ達なのでいろいろ挑戦していきたいと思います。楽しかった!


  4. 反省等

みんな、うんこ言い過ぎ

2012年7月2日月曜日

ショートカットキーで開発効率化(Mac/Eclipse)

先日、参加したAndroid Hackathon in Fukuoka でペアプロを行いました。
普段の自身で作業する中ではあまり気にならない各種操作で意外と時間がかかっていることを感じ、ショートカットまわりのまとめを行うことにしました。

なお、今回はMac、Eclipseを対象としました。

今日の目次はこんな感じです。
  1. Macキー配列のおさらい
  2. 事前準備
  3. Macショートカットキー
  4. Mac Eclipseショートカットキー

  1. Macキー配列のおさらい

MacのJISキーボードは以下のような配置となっています。












以下のボタンはよく利用するので、ボタン名とボタンを表す記号の組み合わせは覚えておくとよいでしょう。

Mac特殊キー
記号 ボタン
Controlボタン
Shiftボタン
Optionボタン
Commandボタン


  2. 事前準備

各種ショートカットを利用する前に、以下の設定を行います。

Control + Space

Eclipseの入力補完とMacOSが標準で持つ検索ユーティリティSpotlightを呼び出すショートカットが重複するので機能をOffにするか、ショートカットの割当を変更します。

システム環境設定 > Spotlight

画面下の「Spotlightメニューのキーボードショートカット」チェックを外すか、別のショートカットを割り当てます。









ファンクションキー

EclipseでF3等のファンクションキーを利用した機能がありますが、Mac標準のキーボード操作では、F3相当の機能を利用するためには、fnキーを押しながらF3等を押下しなければなりません。
これは操作の手間が増えるため、fnキーを押さなくてもファンクションキーとして利用できるように設定を変更します。

システム環境設定 > キーボード

 画面真ん中のチェックボックス「F1、F2などのすべてのキーを標準のファンクションキーとして使用」にチェックを入れてください。









 以上で、事前準備が完了です。


  3. Macショートカットキー

Windowsで利用する標準的なショートカット(コピー、ペースト、保存、全選択等)は、WindowsのCtrlキーをCommandキーに読み替えることでほぼそのまま利用可能です。

ここでは、その他、知っておくと便利なショートカットをまとめます。

Macショートカットキー
オススメ 操作 ショートカットキー 備考
バックスペースfn + deleteショートカットではありませんが…
エスケープ文字Option + ¥ショートカットではありませんが…

行の先頭へ移動Command + ←

行の末尾へ移動Command + →

ページアップfn + ↑

ページダウンfn + ↓


  4. Mac Eclipseショートカットキー

ここでは、Mac Eclipseを利用する際に、知っておくと便利なショートカットをカテゴリごとにまとめます。

編集系ショートカットキー
オススメ 操作 ショートカットキー 備考
コメント追加削除Command + /
Command + Shift + C
複数行のコメントアウト操作

行削除Command + Dカーソルのある行を削除
JavaDocコメント生成Command + Option + J カーソル位置のメンバに
対するJavaDocコメント
の挿入
現在行の移動Option + ↑
Option + ↓
カーソルのある行を上下
に移動
現在行のコピーCommand + Option + ↑
Command + Option + ↓
カーソルのある行を上下
にコピー

コード補完系ショートカットキー
オススメ 操作 ショートカットキー 備考
コード補完Control + Space コード補完。必須。

インポート編成Command + Shift + O 必要なimport文の追加と
不要なimport文の削除
クイックフィックスCommand + 1 警告、エラー箇所で実行。
修正候補を選択して修正。
クイックアシストCommand + 2右辺のみ記載して実行。
Lキーにて左辺補完。

リファクタ系ショートカットキー
オススメ 操作 ショートカットキー 備考
名前の変更Command + Option + R 変数/メソッド/クラス名変更。
参照先も置換可能。

リファクタメニューCommand + Option + T クイックリファクタ
メニューの呼び出し

ソースメニューCommand + Option + S クイックソース
メニューの呼び出し

検索/移動系ショートカットキー
オススメ 操作 ショートカットキー 備考
宣言を開くF3カーソル位置の定義箇所へ
移動

呼び出し階層の表示Control + Option + H カーソル位置の利用箇所の
表示と移動

クイック
アウトライン
Command + O クラス内の変数/メソッド
一覧の表示と移動

最終編集位置Control + Q最終編集位置へ移動


タブ移動Control + fn + ↑
Control + fn + ↓
開いているタブの切替


パースペクティブ
移動
Command + F8開いているパースペクティブ
の切替
型を開くCommand + Shift + T  クラス、インターフェース
のインクリメンタル検索

リソースを開くCommand + Shift + R リソースファイル
のインクリメンタル検索

エラー箇所へ移動Command + .
Command + Shift + .
エラー箇所へ移動(下へ)
エラー箇所へ移動(上へ)

変数利用箇所へ移動Command + K
Command + Shift + K
変数利用箇所へ移動(下へ)
変数利用箇所へ移動(上へ)

実行/デバッグ系ショートカットキー
オススメ 操作 ショートカットキー 備考
実行Command + Shift + F11  前回の構成でプロジェクト
を実行
デバッグ実行Command + F11 前回の構成でプロジェクト
をデバッグ実行
ステップオーバーF6デバッグ時のステップ
オーバー操作。
ステップインF5デバッグ時のステップイン
操作
再開F8デバッグ時の処理再開操作



---------------------------------

以上、Macショートカットキーで開発効率化でした。
上記以外にもオススメのショートカットがありましたら教えてください。

2012年6月21日木曜日

AndroidのSparseArrayは本当に速いのか測定してみた

前回のエントリで紹介したBundleSaverを作成する際に、SparseArrayというクラスの存在を知りました。

SparseArrayは、Android向けにつくられたパフォーマンスに優れたHashMap代用とのことで、その使い方と気になる性能について調べてみました。
実際に測定することでメリットやデメリットがわかったので、ご紹介します。

  1. SparseArrayってなぁに?
  2. どう使うの?
  3. HashMap と SparseArray の性能比較
  4. 考察
  5. まとめ
  6. 参考(計測に利用したクラス)

  1. SparseArrayってなぁに?

SparseArrayは、キーにintを利用することを前提としたHashMapだと考えると分かりやすいかと思います。
(Integerではなく、intです。)

また、SparseArrayでは、値にObject型を格納できますが、値がint, booleanの場合は、それぞれSparseBooleanArray, SparseIntArrayというクラスも用意されています。

内部にはキー用の配列、値用の配列を個別に持ち、配列添字による取得以外は、基本的に二分木探索で目的の値を取得するつくりになっています。
また、保持するキーと値のペアを削除する際は、内部的に削除フラグを立て、随時寄せる処理を行っていました。
おそらく配列を有効利用することで不要なメモリ消費を押さえる目的と思われます。

  2. どう使うの?

基本的にはHashMapと同様です。

SparseArray.keyAt(int index)で、キー配列の添字に該当するキーを取得します。
SparseArray.valueAt(int index)で、値配列の添字に該当するキーを取得します。
もちろん、キーが分かっているので、SparseArray.get(int key)でも構いません。

  3. HashMap と SparseArray の性能比較

SparseArrayは、Androidの静的解析ツールLintでも対応すべき対策として指摘されるとのことなので、効率的なのだろうとは思いますが、実際にどういう面で効率的なのかが分からなかったので、性能調査を行いました。

調査環境
  • Android Emulator
  • Android 2.3.3

調査方法
  • onCreate時に、HashMapとSparseArrayを生成し、任意の数のキー、値のペアを操作する。
  • 操作内容は、put, getとし、対象の全キー操作完了までの時間を計測する。
  • なお、キー一覧の生成時間は計測時間から除外する。

計測結果
 計測結果は以下のとおり

Put操作















Get操作















Put/Get操作の合計















  4. 考察


上記結果から、処理対象が増加するほどSparseArrayのほうがパフォーマンスが出ると見なすことができます。

興味深いのは、処理時間の内訳です。
ご覧のとおり、put処理では、HashMapがかなり時間がかかっているにも関わらず、get処理では、HashMapのほうが処理速度は速くなっています。

これはそれぞれが採用するアルゴリズムの違いが差として現れていると考えられます。
HashMapが採用するアルゴリズムはハッシュ探索なので、値格納時にハッシュ関数処理とハッシュ表の作成処理が必要です。
その代わり、探索はハッシュ関数による格納位置を求めるだけですみます。
これがputが遅く、getが速い理由です。

一方、SparseArrayは探索アルゴリズムに二分探索木を採用しています。
これは、値格納時にキーの大小比較を行う程度で済みますが、探索は二分探索木で行われるため、線形探索に比べれば圧倒的に速いとはいえ、
件数が多くなるほど時間がかかるようになってしまいます。

メモリの観点から

メモリ利用率からも測定を行いました。
(とはいえ、GC発生回数という簡易な測定です…。目安にはなるかと思います。)

GC発生回数















HashMapのほうがGC発生頻度が高く、SparseArrayがメモリを効率的に利用していることがわかります。


  5. まとめ 

まとめです。
  • 速度面、負荷面の観点で、SparseArrayはHashMapより高いパフォーマンスを発揮する。
  • ただし、Put後のGet処理が多く、性能が求められる用途(キャッシュなど)ではHashMapの利用を検討してもよい。
  • その際はソフトリファレンス等を効果的に使い、メモリ圧迫を回避する手段を講じること。


  6. 参考(計測に利用したクラス)

性能測定で利用したクラスです。
これらのTaskを別途準備した計測用のクラスに渡して計測を行いました。

こういう計測を行ったほうが効果的だよというのがあればご指摘もらえればと思います。


-------------------
以上です。HashMapとSparseArrayの使い分けに関して、何かの参考になれば幸いです。
ではでは。


2012年6月16日土曜日

振る舞いのよいAndroidアプリのために。BundleSaver。


Androidで、Bundleへの保存/復元を自動で行ってくれるユーティリティをつくりました。
GitHub / monochromegane / BundleSaver

2012/07/08
BundleSaverのバージョンアップと使用手順の変更を行いました。
下記ページもあわせてご覧ください。
続・振る舞いのよいAndroidアプリのために。StateSaver。



今回のアジェンダです。
  1. Bundleってなぁに?
  2. Bundleの問題点
  3. BundleSaverで解決

  1. Bundleってなぁに?

AndroidのActivityにはライフサイクルがあります。
別のアプリが前面に来るなどして、バックグラウンドにまわった後、他のアプリによってメモリが不足した場合にActivityが破棄されることがあります。
このとき、メモリ上にだけ展開されていたインスタンス変数などの値も破棄されてしまいます。

再度呼び出されるときは、もう一度Activityを生成しなおすため、前回の状態は失われています。
ユーザ側の立場に立ったとき、前回と同じ状態になるよう復元する必要があります。
このとき、状態を保存、復元する入り口としてAndroidが準備してくれているのがBundleです。

実装方法などは、以下にわかりやすくまとまっています。
Y.A.M の 雑記帳 / Android Bundle で状態を保存


  2. Bundleの問題点

Bundleは実装内容は決まりきっているわりに、インスタンス変数といったアプリ開発中に随時変わっていくところを対象としているので、めんどくさくなってついつい変数との整合性をあわせるのを後回しにしがちです。

保存する必要がある新しい変数つくると、それに応じたreadする処理、writeする処理を書かなくてはならないというのが問題だと思います。

  3. BundleSaverで解決

BundleSaverは、変数の宣言時にアノテーションでBundle対象であることを記載するだけで、保存、復元は自動で行ってくれるユーティリティです。

こんな感じで使います。


対象となる型は、Bundleに格納できるもの + α です。
プリミティブ型、ラッパーオブジェクト、Bundle, Parcelable, Serializable などが格納できます。
詳しくはGitHub上のREADMEをご覧ください。

実装としては、対象のActivityに対して、BundleTargetアノテーションが設定されているインスタンス変数をリクレクションで取得、変数名からキーを生成してBundleへ格納。
復元時は、その逆を行うといった感じです。

対象となるインスタンス変数にアノテーションをつけるだけで、保存/復元処理はBundleSaverを呼ぶだけなので、使いやすくなるんじゃないかと思います。
状態の保存/復元は地味ですが、ユーザ側にとって振る舞いのよいアプリケーションをつくるのに重要な処理なので、ぜひ使ってみてください。

-------------------------
ここはこうした方がよいよとかご指摘ありましたら、教えてもらえれば幸いです。
ではでは。



Android Night in Fukuoka vol.26 に参加しました

6/4にAndroid Night in Fukuoka vol.26に参加してきました。

Android Night in Fukuoaka vol.26

今回もLT中心でした。
内容をざっとまとめておきます。


Lightning Talk


Google I/O報告会2012のお知らせ

6/27から開催されるGoogle I/Oの報告会が全国各地で開催されるとのこと。
Google I/O報告会2012

開催から一週間ちょいの最新ネタが福岡で聞けるスバらしい会。これは行きます。


NFC

NFCアプリでiDmを利用する際の注意事項について。


情報整理術

未来から来たカナイさんによる21世紀の情報整理術について。電子書籍化の取り組みとそれによって得たもの。


JenkinsとXFD

XFD(eXtream Feedback Device)と呼ばれる「過激な」フィードバック装置の紹介。
Jenkinsと組み合わせてテスト、ビルド失敗時にランプがつく装置のデモ。
実際に使っているプロジェクトがあるとのことで、こういう遊び心がある風土は見習いたいです。


Androidの描画処理

Androidの描画処理をクラス図とシーケンス図を用いて説明。Viewのinvalidate処理を追っていくと、最終的にHandlerを継承した親Viewでキューへの登録処理が行われますよという話。
Viewの中でもHandlerが最終的に利用されており、Looper等もうまく利用すれば面白いことができる(かも)。

Androidのソースは継続的に読む機会をつくりたいな。


アプリ紹介:SoundFire

NFC、音声認識をうまく利用したYoutube再生プレイヤー。NFC技術単体では興味が湧かなかったけど、アプリ起動など具体的に使うシーンを考えると面白くなってくるなと思えるLTでした。


アプリ紹介:日本Androidの会福岡支部アプリ

同じくNFCと組み合わせた日本Androidの会福岡支部用のアプリ開発進捗報告。出欠確認に利用できるのは、いろいろと応用ができそう。 

  


ソフトウェア勉強会について


タガさん発案のソフトウェア系の勉強会の方向性について。基礎コースとゴリゴリコースに分かれてやっていくことになりました。
ゴリゴリコースに参加予定。モノをつくるというより、ペアプロなどでお互いの開発スキルを伸ばしていく会になりそう。かなり楽しみ。



所感

今回もハードからソフトまでAndroidの切り口で色々な話が聞けました。


この会のよいところは、Androidというカテゴリでいろんな分野のひとが集まること。
普段興味を持っている範囲から踏み出したところの話を聞いて、自分の中で考えが広がっていくところだと思います。
興味を持ったところは、直接LTした人と話をしてもよし、更に特化した勉強会のお知らせも会の中であるので、そっちに行ってもよし。

いい情報交換の場として参加させてもらっています。

次回は7/2です。Androidに興味ある方は是非。

Android Night in Fukuoka Vol.27

アジャイルサムライ福岡道場 零の巻 に行ってきました。

6/14にアジャイルサムライ福岡道場 零の巻 に行ってきました。

今回は、零回ということで、参加者の想いや今後の方針を確認がメインの会でした。
特に、ワールドカフェでのお題「価値ある成果」とは何かを話し合うことで、参加者が今後、アジャイルに関わらず、システム開発に関わるときの、根本の大事なことを改めて気づかせてもらえた、いい会だったと思います。

アジェンダは以下のとおり
  1. チェックイン
  2. LT: 僕のアジャイル黒歴史と希望
  3. ワールドカフェ
  4. 今後の方針
  5. その他、関連イベント紹介

   1. チェックイン

まずは自己紹介。
参加者は20名程度。皆さん、ほぼ何らかのかたちで開発に携わっているみたいです。
アジャイル経験者は1/4程度。
ちなみに全部男性でしたw

発注側の立場の方もいらっしゃったので、偏らない意見交換の場になれるといいですね。


   2. LT: 僕のアジャイル黒歴史と希望


@gokingさんによるLT。
アジャイルプロジェクトの失敗談を通して、顧客を巻き込む重要さと難しさを語っていただきました。
現在、顧客と一緒になったアジャイルプロジェクトを進めれているとのことで、そのあたりの情報を共有していけたらとのことでした。

実践の話は、一番みんな聞きたいところだと思うので今後期待です。



   3. ワールドカフェ

ワールドカフェって知ってましたか。
テーブルごとに話し合いを行う、メンバ交代で意見交換を効率的に行う形式みたいです。

今回のような組織やコミュニティの比較的多人数の集まりで、設定したテーマに関して、ダイナミックで協働的な話し合いの場を作り出すのに効果的とのこと。
 
お題は「価値ある成果」とは何か。です。

だいたい、各テーブルでこんな感じで話が進んだと思います。

  そもそもアジャイルってどうなの?

  未経験者が多いため、アジャイルって使えるの?という疑問を経験者に聞くところから。
経験者からも失敗談、主に、開発側のイテレーションに対する経験不足、顧客側との相互理解の不足が原因の失敗談を聞くことができました。

アジャイルって難しい…?


  価値ある成果って?


次は価値ある成果とは、を話しましたが、ここは開発側、発注側の立場の違いだけでなく、開発側の中だけでも意見がばらばらなところでした。
システム、コスト、スケジュール、要求どおり、次につながること、etc...


  価値ある成果を達成するには?


では、その価値ある成果を達成するには、どうしたらよいの?という話。
全ての価値を達成するのは無理。無限のコストと無限の期間がなければ。
そこでトレードオフが発生します。
何を捨てて、何を優先するのか。
捨てることに対して、「理解を得ながら」システムをつくっていかなければ、お互いが不幸になる。
価値ある成果を達成するためには、お互いがシステムをつくるのに同じ土俵に立って逐一、理解を深め合いながらシステムに関わっていくことが必要。


  もう一度、価値ある成果って?

逆説的にはなりますが、「何を価値あるものとみなすか」それを相互が、逐一理解を深めながら進めた結果が、価値ある成果なのだと思います。

価値観は、みんなそれぞれ違う。
そこを埋めていく過程こそが成果につながる。

何を価値とみなすかを話していく。共有していく。
お互いに納得済みのゴールが価値ある成果。

こんな感じでしょうか。

その「目的」のためにアジャイルや、飲みニケーションといった「手段」をつかっていくのだということを忘れないようにしなければいけないと思いました。


(ああ、上司が何度も苦労して何度も語りかけてきたところだ、これ…。)




   4. 今後の方針
  • 月1の頻度で実施
  • まずは輪読から
  • 事前に2章ずつ読んでくること
  • 各節ごとに話し合い、疑問点、まとめを行う
  • 次回、7/27(金)を予定
  • Facebookにグループ作成して、やりとりを行う

アジャイル道場なので、やり方もアジャイルで適宜変えていきましょう。 by @goking




   5.その他、関連イベント紹介


7月のアジャイル関連イベントの紹介
  • スクラムブートキャンプ
  • Coderetreat
  • Jenkins勉強会



詳細は個別にFacebook、Twitterで告知。


------------------------------
アジャイルサムライ福岡道場。興味あるかたはATND等で告知しますので是非参加してください。ではでは。



2012年6月14日木曜日

AndroidのListViewを速くするためにやったこと

先日公開した、電話帳アプリ「OneHand Dialer」ですが、品質、性能面で問題ありとのご指摘を受けました。
今回は、備忘録も兼ねて、対策内容をまとめておきます。


Android ListViewを速くするためにやったこと
  1. 現象と原因
  2. 正規表現の使用は極力避ける
  3. Bitmapはキャッシュする
  4. BitmapはBitmapFactory.Optionsを使って縮小する
  5. おまけ:GC発生箇所の調査環境構築


  1. 現象と原因

以下の現象が発生するとのことで、調査を行いました。

・端末:GALAXYNexus(Android 4.0)
・起動時の読み込みに5秒ほどかかる
・データ件数は300〜400件程度
・その他、よく落ちるとのこと(詳細不明)

うーん…。

自分の端末での動作確認のときは、そんなに連絡先の件数が多くなかったこともあり、再現できてなかったのですが、 同等件数のデータと顔写真データが設定されている端末での動作確認を行ったところ起動時に時間がかかる現象は発生させることができました。

よく落ちる現象は手元の端末では再現させることができなかったのですが、別途Android4.0の環境で動作確認を行ってみたいと思います。

原因は、連絡先一覧の取得〜表示処理までに大量のGCが発生していたためでした。
以下、個別の原因と対策です。


  2. 正規表現の使用は極力避ける

OneHand Dialerでは、あいまいソートという機能により、ふりがなに、ひらがな/全角カタカナ/半角カタカナが混在していても、同一視して並べ替える機能があります。
実装には、Comparatorインターフェースを実装して独自の比較を定義しています。

その中で、ひらがな/全角カタカナ/半角カタカナなどを区別するために正規表現を利用していたのですが、そこで、短命オブジェクトが大量に生成されており、GCの対象となっていました。

件数が多くなるほどcompareメソッドが呼ばれる回数が多くなるため、GC発生回数が増えたというわけです。

今回は、正規表現による判定をUnicodeBlockで代用することで回避できました。


また、大文字、小文字の統一も当初、正規表現で判定して、個別にtoUpperCaseメソッドを行っていたのですが、これも短命オブジェクトを大量に生成していたため、最終的な比較処理で利用していたcompareToメソッドをcompareToIgnoreCaseに変更することで条件を除外する対策も行いました。

今回は、代用する条件がありましたが、正規表現でしか表現できない条件を繰り返し利用する場合は、性能面で注意が必要だと思います。
何か対策をご存知のかたがいらっしゃれば、教えていただければと思います。


  3. Bitmapはキャッシュする

OneHand Dialerでは、連絡帳一覧に顔写真を表示しています。
また、ImageViewの角を丸く見せるため、Bitmap生成処理が多少複雑になっており、これらが、ListViewのgetViewの度に呼ばれることで、メモリを圧迫していました。

対策として、Bitmapの一覧をキャッシュするよう変更しました。
また、キャッシュにはソフトリファレンスを利用することで、キャッシュによるメモリ圧迫を回避しています。

実装に関しては、以下が参考になると思います。
Bitmapのキャッシュ
Techfirm Android Lab / AsyncTaskでユーザビリティを向上させる
ソフトリファレンスによるキャッシュ
Techfirm Android Lab / CacheオブジェクトにはSoftReferenceを


  4. BitmapはBitmapFactory.Optionsを使って縮小する

大きなサイズのBitmap生成はコストが高い処理です。
リサイズもできますが、元のサイズのデータを一旦メモリに展開して行うため、非効率的です。

今回は、BitmapFactory.Optionsを使った効率的なBitmapの生成を行うことで対応しました。

AndroidのBitmapFactory.Optionsを使うと、メモリ展開前に画像サイズを取得できるため、最初からリサイズした状態で(少ないメモリで)Bitmapを生成することが可能です。

ポイントは、inSampleSizeプロパティです。
リサイズの縮尺を整数で指定します。1で等倍、2で1/2のサイズにリサイズされます。
ここでは、viewのサイズに合わせたサイズになるように値を求めています。


BitmapFactory.Optionsの使い方は以下を参考にしました。
効率的なBitmapの生成
iPhone充日記 / ListViewに画像を非同期で読み込む場合の注意


  5. おまけ:GC発生箇所の調査環境構築

GCの発生箇所の特定は以下を参考にしました。

MAT環境の構築
電脳羊(Android Dream)/ Eclipseで使うMemory Analyzerのインストール
※自分の環境では、Eclipseとの連動のため、ここにある手順に加えて、Eclipse -> 環境設定 -> Android -> DDMS -> HPROFオプションで「Open in Eclipse」を選択する必要がありました。

MATによるヒープタンプの見方
Bescottee / メモリリークを発見!Androidアプリのメモリ解析手法

※上記のMATに加え、DDMSタブのAllocation Trackerも参考にしました。

以上です、どなたか参考になれば幸いです。ではでは。


2012年6月11日月曜日

Android UI について

今回、OneHand Dialerという片手で使える電話帳をリリースしました。

電話帳: OneHand Dialer [Free]

アプリ作成にあたっては、自身が電話帳アプリ、ひいてはAndroidのUIで使いにくいなと思っていた点を解消できればと思って作成しました。

無事リリースできたので、つくっているときに感じたことや今後のことをまとめてみました。


AndroidのUIで使いにくいと感じていた点


Androidをはじめ、タッチパネルではフリップやタップ操作により、直感的な操作が行えるようになりましたが、反面、特定のスクロールアクションや画面内の各ボタンまで指を運ぶ必要があるため、いくら慣れても操作に一定の時間がかかってしまう不満がありました。

AndroidのUIはPC操作でいうところのマウスだけ与えられた状態に近いと思います。
よく使うアプリほど、キーボードショートカットに該当する操作が提供されるべきだと考えます。


電話帳アプリへの不満点


特に電話帳アプリでは、思ったときにすぐ連絡先へアクセスしたいにも関わらず、

・一覧のスクロールが行き過ぎる
・一覧のスクロールが片手操作しづらい
・検索ダイアログが上部にあったりして、片手持ちの際に届かない
・タッチ場所により、ソフトウェアキーボードが出たり消えたりしてわずらわしい

といった邪魔をする要因があり、やきもきしていました。
(スマートフォンなのに電話が一番かけづらい…)


OneHand Dialerでの対策


上記を解決するため、わかりやすい、かつ、慣れるほど短い操作で使えることを目標にデザインを考えてみました。

基本思想は以下です。

・よく利用する操作は手元、画面下部に集約する
・リスト操作は大きな動きと細かい動きを制御できるようにする

基本画面は以下です。


・操作のための固定キーボードを提供
検索キーワードはここから入力。
下部のコマンド群はリスト内容によって提供操作を変更。

・リスト操作は上下キーによるカーソル移動とフリップ操作を連動
また、上下キーは長押しによる速い移動が可能。


キーボードの検索キーワード入力、上下キーでのリスト移動、コマンドボタン、これらが画面下部に集約できたことで操作が全て手元で行え、電話発信にかかる手番は最小限にとどめることができたと思います。


今後


今回のアプリ作成にあたり、AndroidのUIパターンを参考にしてみましたが、リスト画面の操作向上に対するパターンは探した限りなかったと思います。
ただ、画面下部に集約するというUIデザインは、いわゆるNavigation BarとかAction Bar, Quick Actionを参考にしました。

これらをあわせて、リスト操作を手元で行えるコマンド部品というのを下部に配置するという方針に至りました。
リストの表示部分が少なくなるという課題はありますが、操作性としては一定の効果は出せたと思います。

今後は、それらをもう少し煮詰めて、いわゆるキーボードのショートカットを実行できるコマンド群を入力する汎用的な部品をつくってみたいなと考えています。
コマンド群はソフトウェアキーボードなので、画面に応じて実行コマンドを変更できるので汎用性は問題ないはずです。
(リストであれば、細かい動きのための上下キーは欲しいところ)

コマンドUIパターンはライトユーザ、ヘビーユーザのどちらも満足できる操作感を実現する架け橋になる(かな?)


2012年5月28日月曜日

JavaQne(じゃばきゅん) Fukuoka 2012 に参加しました(後編)

JavaQneはまだまだ続きます。
JavaQne(じゃばきゅん) Fukuoka 2012 に参加しました(前編)
JavaQne(じゃばきゅん) Fukuoka 2012 に参加しました(中編)

JavaFX and Web Integration

リッチなUIでJavaの表現力を大幅に強化するJavaFXと、FXに含まれるWebコンポーネントを利用した新しいマッシュアップのかたちについての講演でした。

以下、簡単なまとめです。

今後の方向性

  • JavaSE8の標準APIに。
  • GUIビルダーの提供(SceneBuilder)
  • オープン化

JavaFXのWebコンポーネントの概要

  • 本格的なブラウザを内蔵
  • Webkitベース。HTML5の一部をサポート。JavaScriptエンジン。
  • DOMアクセス、SVGサポート

利用シーン

  • Webコンテンツの表示(ローカル生成コンテンツ含む)
  • Webアプリケーションの埋め込み
  • JavaからWebアプリをコントロール
  • Webアプリと多彩なJavaライブラリを融合

Web Integration

上記のJavaFXに含まれるWebコンポーネントを利用したWebアプリとの連携について各種デモを交えながらのお話。

Webコンポーネントは、Javaアプリの中にブラウザ機能を組み込むことができます。
そして、JSObjectオブジェクトを通して、ブラウザのJavaScriptとJavaアプリがやり取りができるのです。
これにより、JavaアプリからWebページを動的に操作することができるようになります。

Androidをやるかたは、WebViewのaddJavascriptInterface()メソッドによる操作をイメージしてもらえばわかりやすいかと思います。

また、JavaFXのWebViewはシングルスレッドポリシーであり、WebコンポーネントにはJavaFXのアプリケーションスレッドからアクセスする必要があるとのことでしたが、これもAndroidのUIスレッドとHandlerと同様の関係性ととらえることができます。

iOSとJavaFX

上記のJavaFXに含まれるWebコンポーネントを利用したWebアプリとの連携について各また、実験的な取り組みとしてiOSのアプリにJavaランタイムごと含めてJavaFXのアプリを動かすデモも見せていただくことができました。(あくまで実験とのこと)
いつか、iOSアプリもJavaで開発できる日が来るかもしれません。

JavaFXはまったく使ったことがなかったですが、Androidをやったあとなら意外とすんなりと入れるかもしれません。



The New JSR-107 Caching Standard

パフォーマンス確保のためのJavaのオブジェクトキャッシュの仕様についての講演でした。

以下、簡単なまとめです。

JCacheについて

Javaでのオブジェクトキャッシュ仕様であるJCache。
既に存在する各ベンダーによるキャッシング技術を標準APIにより隠蔽するものことです。
キャッシュ統計の取得や、アイソレーションレベルを指定したトランザクションの仕組みなどが提供されるみたいですね。

実装

以下のAPIを利用してキャッシュを管理します。

  • CacheManager:キャッシュの検索、ライフサイクル管理
  • CacheBuilder:キャッシュの生成
  • Cache:キャッシュ操作用のメソッドを提供

またアノテーションが提供されており、それらを利用することで利用側、提供側がキャッシュを意識しないロジックで記述することが可能。

  1. Service クラスでキャッシュ対象にアノテーションをつける。
  2. 使う側では、Serviceをインジェクションする。

これによりDIコンテナがメソッド呼出し前に割り込んでキャッシュを取り出す。
アノテーションのみで処理を意識しないというのはありがたいかも。

比較的小さなAPIみたいなので、興味があれば使ってみたいと思います。
(Mavenでjavax.cacheをいれればつかえるみたいです。 by @yuutoさん)



近頃のNetBeans

きしださんのライブコーディングによるNetBeansの新機能紹介。
ここは、JavaQneに来られた方だけが得られた情報がたくさんでした。
内容はあえて書きません!w

きしださんサイコー。



所感

新しい情報をたくさん得ることができました。ひとりだとどうしても、情報収集の幅が限られてくるので、こういう機会は非常にありがたいです。
このイベントを開催してくれた方々、参加してくれた方々に感謝したいと思います。
ぱちぱちぱちぱち!

それと、最近だと普通なのかもしれませんが、講演の間、平行して#javaqneハッシュタグで関連する情報やらツッコミやらが飛び交ってて、静かに会場の一体感が高まっていく感じが楽しかったです。
学生時代の授業中に手紙まわしてたのを思い出しました。
リアルタイム性は比較になりませんが。

今回、自分も有用な情報を提供したかったのですが、唯一のファボられが冒頭のJavaRapをYoutubeで見つけたつぶやきでした。精進しよう...。


おまけ:The "Java Life" Rap Music Video (Japanese Subtitles)

冒頭のJavaラップ(字幕入り)はこちら


JavaQne(じゃばきゅん) Fukuoka 2012 に参加しました(中編)

前編からの続きです。
JavaQne(じゃばきゅん) Fukuoka 2012 に参加しました(前編)

Java SE 7、そしてJava SE 8

今までのJavaの仕様策定に関する紆余曲折の歴史を楽しそうに語る櫻庭さんが印象的な講演でした。

講演内容は、Java SE7, 8 の追加機能についてです。
基本的にはIT Proの「Java SE 7徹底理解」を読んでくださいとのことでしたw

ポイントまとめてみます。

Java SE 7について

Project Coin

Project Coin(文法の小さな変更)は以下のとおりです。
詳細は「Java SE 7徹底理解」に譲ります。

  • switchでの文字列
  • 例外のmulti catch
  • safe rethrow
  • ジェネリクスの省略記法(ダイヤモンド演算子)
  • try-with-resources
  • 簡潔な可変長引数メソッド

try-with-resourcesのみ解説がありました。
こんな感じでAutoCloseableを実装したクラスを以下の構文で記述するとclose処理をJava側で自動でやってくれるとのことです。
コードが簡潔になってclose漏れがなくなるので積極的に使っていくべき構文だと思います。
close処理が必要な標準のストリーム系のクラスは既にAutoCloseableがimplementされているみたいなので、その辺も意識しなくてよいみたいです。


NIO.2

NIO.2は新しいファイルシステムAPIです。
ファイルのコピー、シンボリックリンクなどのファイル操作ユーティリティが(やっと)提供されました。

さようなら、FileInputStream、さようならDecoratorで記述する長い処理。
FileVisitorクラスが提供され、ディレクトリツリーの検索も簡単にできるようです。
ここについては、別途調べてみようと思います。

InvokeDynamic

InvokeDynamicは、JVM上で動作するJava以外の言語でのメソッド呼出しのための仕組みみたいです。
Java言語でプログラム記述している分には意識することがない機能ですが、例えばJRubyのような言語はこの機能を使うことで呼出しが最適化されて、かなり性能があがるみたいです。

Fork/Join Framework

Fork/Join Frameworkは、マルチコア環境での効率的なタスク処理をサポートするためのフレームワークのようです。
この辺は、もう少し勉強が必要なので、機会があれば別途まとめたいと思います。


Java SE 8について

Project Lambda

ラムダと読みます。読めませんでした。ランバダと心の中で読んでいました。
以下、これがラムダと読めなかった人レベルの理解で書いてあるので、詳しい方のつっこみを期待します。

Java SE 8 では ラムダ式(記述方法)が導入されます。
よくセットで使われるクロージャが導入されるわけではないことに注意。
クロージャは「レキシカルスコープを伴うファーストクラスの関数(無名関数)」らしいです。
相変わらずJavaでは関数をオブジェクトとして使えないということです。
無名クラスまでですね。

Javaでのラムダ式は、ある条件での記述を簡単にするための新しい構文という理解です。

どういうときの記述を簡単にできるかというと、メソッドがひとつしかないインターフェースを実装した無名クラスのインスタンス生成時に簡易に記述することができます。

ラムダ式によるビフォーアフターが以下です。
AndroidのOnClickLitenerの場合、(注:Androidではまだラムダは使えません)

なんということでしょう。定義のためだけに記述していた無名クラスの記述が
こんなにすっきりしていましました。まさに匠。

匠はさらに技を見せてくれます。

型すら不要になってしまいました。まさに匠。

ラムダ式は以下の記述で利用できます。
(引数, 引数, ...) -> メソッド本体

この簡潔なコードは、前に述べたFork/Join Frameworkで処理ごとにたくさんのタスクを記述するのに効果を発揮するみたいです。

コードがすっきりとするので、これも積極的に導入していきたい機能です。
櫻庭さんの以下のサイトで勉強しました。上記以外にもっと機能があるみたいなので興味があるかたは是非。
Java in the Box Annex


Jigsaw Project


パッケージングに関する仕様をまとめたものみたいですが、時間切れであまり触れられませんでした。
おいおい調べます。



ラムダが長くなってしまった... 後編に続きます。
JavaQne(じゃばきゅん) Fukuoka 2012 に参加しました(後編)

JavaQne(じゃばきゅん) Fukuoka 2012 に参加しました(前編)

5/26に、JavaQne(じゃばきゅん) Fukuoka 2012 に参加してきました。

JavaQne(じゃばきゅん) Fukuoka 2012

東京であったJavaOneを福岡でやろうという企画で、実際にJavaOne東京で話をした人もお呼びして、Javaの話をいろいろ聞いちゃおうというイベントでした。

福岡にいるとなかなか東京の情報を直接聞く機会もないので、非常に有意義なイベントだったと思います。なにより、雰囲気が堅苦しくなくてよかったですね。

タイムテーブルはこんな感じです。

Java EE 6 からクラウド対応に向かって日本オラクル寺田 佳央 (@yoshioterada)
Java SE 7、そしてJava SE 8Java in the Box櫻庭 祐一 (@skrb)
JavaFX and Web Integration日本オラクル関谷 和愛 (@kazuchika)
The New JSR-107 Caching Standardレッドハット
日本オラクル
木村 貴由(@nekop)
寺田 佳央 (@yoshioterada)
近頃のNetBeansJavaコミュ@九州きしだ なおき(@kis)

以下、それぞれの講演のまとめメモです。

Java EE 6 からクラウド対応に向かって

冒頭、謎のJavaのラッパー(Adapterパターンではない)が踊り歌うイメージビデオが流れ、にこやかな雰囲気で講演が始まりました。

以前の難しい、開発効率が悪い、面倒というJava EE のイメージは捨ててください、
Java EE 5 からはかんたん開発へ方向転換し、EE 6 からは本番適用レベルになっていますよというお話でした。
具体的には、仕様の軽量化、拡張性、開発効率の向上が挙げられています。

仕様の軽量化

仕様の軽量化という観点では、不要なAPIの整理はもちろんのこと、プロファイルという単位で仕様が分割され、アプリケーションサーバなどの実装側が必要最小限のプロファイルのみを採用することで、軽量化が図られるそうです。
Webアプリの仕様はWebプロファイルとしてまとめられており、例えばこれを実装したアプリケーションサーバは4秒程度で起動するとのことです。

拡張性

拡張性は、外部のフレームワーク(Spring, Seasar2 ...)の組み込み定義が容易になる例を提示されていました。
Web.xmlへ定義をincludeするようなイメージで、組み込みのための定義を外部ファイルに切り出すことができるようです。

開発効率の向上

開発効率の向上という点では、Java Server FacesによるリッチなUIを持ったアプリケーションの開発環境(VB的な画面ビルダー)を例に紹介しています。

また、個人的に一番よいなと思えたのは、EJBの単体テストを容易にするための仕組みが提供されていることでした。
今までのEJBはデプロイとコンテナ起動が必要で単体テストのコストが非常に高いのが問題でした。

EE 6 ではSE環境でも
"EJBContainer container = EJBContainer.createEJBContainer(); "
のようにコンテナを取得することができるので、JUnitを利用した単体テストが容易になっているみたいです。

デプロイが不要なのはうれしいところです。

Tomcat見直し運動

上記をふまえた、講演者の寺田さんがひとり奮戦しているw、Tomcat見直し運動。Tomcatの提供するServlet, JSPに結局は各種フレームワークを加えて利用しているのであれば、Java EE の標準技術で十分対応できて、かつ軽量ですよ。
環境構築にやたらと時間かけなくていいですよということみたいです。

Java EE 7 からはクラウドのPaaS環境へ対応し、オートスケール、DBのマルチテナントを含めたJavaプラットフォームとして提供していくJava EE環境。

今後のアプリケーション開発ではEEという選択肢が増えました。



長くなってきたので中編にまわします。次は櫻庭さんの講演についてです。
JavaQne(じゃばきゅん) Fukuoka 2012 に参加しました(中編)


2012年5月19日土曜日

Android Night in Fukuoka Vol.25 に参加しました。

5/14に、Android Night in Fukuoka Vol.25 に参加してきました。
Android Night in Fukuoka Vol.25

久々の参加で、顔ぶれもずいぶん変わっていましたが、飲み物片手のLTなど、
ゆるーい雰囲気は変わらずで安心しました。

今回はLT中心。皆さん積極的で3時間弱の会があっという間でした。

気になったLTは、「ユーザ目線のアプリ開発」と「Native Driverを使ってみた」
の2本。
自分なりの考えを、他の納得できる事例を交えながら、また、詳細にプレゼンする
スキルは見習っていきたいところです。

今回、自分もLTを行いました。
資料をSlideShareにアップしたので、よければご覧ください。

さくさくAndroid開発 

AndroidでMVCモデルの開発を行うためにつくったフレームワークを紹介して
います。
フレームワークは今後も拡張予定です。ブログでも経過報告していきます。

ちなみに次回のAndroid Night は、6/4です。興味のある方はぜひ。
Android Night in Fukuoka Vol.26