2013年12月12日木曜日

Androidアプリプログラマとして振り返ってみる

Android Advent Calendar 2013 12日目の記事です。

勢いでAdvent Calendarにエントリしたものの、最近新しいことあんまり触ってないし、
ndkでいろいろやっているのですが、記事にするほど自分の中で整理されていません。
前日までのエントリでみなさんとてもおもしろい記事を書いていてどうしたものかと思っております。

ただ、Androidアプリプログラマとしてもう3年以上も立つ訳で、これを機会になにをやってきたかを整理してみたら、
なんだか車輪の再発明的なことをたくさんやってきたような気がします。
ただ、実装しているときにはそれは気がついておらず、後で結果的に車輪の再発明になったものがほとんどでした。

今回はそれについて振り返ってみようかなと思います。

DownloaManagerrの実装

昔ブラウザアプリを作っていたのですが、
その当時Android2.2ではDownloadManagerというものはなく、
自分で実装する必要がありました。

そこで、Link先のMIMEタイプがpdfだったりdocだったりしたら、
Threadをつくり、その中でHTTPのgetでデータを取得し、
OutputFileStreamでデータをファイルに書き出すということをしました。
もちろん、Notificationに進捗率の表示だったり、タップしたらキャンセルを行うという処理もしました。

これが面倒くさかったのは、エラー処理をいろいろしなければいけなくて、
  • SDカードがないとき
  • SDカードが途中で引っこ抜いたとき/マウント解除したとき
  • 通信が途中で切れた時
などなど、例外処理やらif文でエラー処理やらを行わなければなりませんでした。

2sprintなので、だいたい1ヶ月ぐらいの実装でしたが(今考えると結構時間使ったなぁ。)、
最後の最後まで、テストしてエラー処理を追加してを行っていた気がします。

しかし、Android2.3からはDownloadManagerが使えるようになったので、
Android2.3以降はこの実装は使う必要がなくなったわけです。
もっと早くDownloadManagerが使えるようになってればこんな苦労はしなかったのに。。。。

FaceBook型メニュー(Drawer)の実装

Facebook型のメニューは
  • RelativeLayoutにViewを2枚重ねる
  • 左上のメニューボタンを押されたらTranslateAnimationで上のViewを左に移動
  • アニメーションが終わった時点で、View.layout(メニューの幅、0, view.getRight(), view.getBottom())で上のViewを左に余白を作ってlayoutして、requestLayout()
  • closeはその逆
をして実装しました。
(実際はいろいろ細かい小細工をして苦労させられました。。。)

こちらは、AndroidではNavigation Drawerと呼ばれ
今は、DrawerLayoutを使って簡単に実装できます。
http://developer.android.com/training/implementing-navigation/nav-drawer.html

当時はこれ実装するのはすんごく苦労したんですよ。。。

Pull to refreshの実装

あのtwitterアプリでおなじみの引っ張って更新する
pull to refresh。
これも頑張って実装しました。

これは、上のツールバーにViewを隠しておいて、
コンテンツのViewをスクロール可能だったらコンテンツのViewにイベントを流して
スクロールさせ、
スクロールできないところまでスクロールしたら、
今度はイベントをコンテンツの外側のLayoutに渡して、余白のViewをすこしずつ下にさげるという実装だった気がします。
イベントをどこに渡すかどうかの判断はonInterceptTouchEvent()だったかな?
ここら辺の実装はすごく苦労した割にはよく覚えていないのです。

ただこれはいろんあバージョンをつくってためしてみました。
ListViewを使った結滞な実装もありました。

しばらくはこの自作のpull to refreshを使っていたのですが、
あるとき、スクロールがかくかくするというバグが発生し、
そのときボスが見つけてきてくれた
https://github.com/chrisbanes/Android-PullToRefresh/
と置き換えてためしてみることになりました。
今は有名なライブラリですが、当時はあまり使われていなかった気がします。

試して見たところ、実は原因は別のところにあったようで、
動作的にはあまりかわりませんでした。
(実装見てみると、自分が書いたコードとほとんど似たようなものだったので、
当然ですが。)

で、結局オープンソースのライブラリの方が安定していていいだろうということになり、
私が作ったコードは使わないことになってしまいました。
これは悔しい思いもしましたが、
今思い返すと最初からライブラリを探していれば、その工数をべつなことに費やすことができたのでは・・・と思ってしまいます。

まとめ

今は必要で一生懸命実装しても
  • 後々そのコンポーネントが標準で用意されるかもしれない
  • オープンソースでライブラリがあるかもしれない。
ということがあります。

前者は逆に言えば後方互換性をかんがえると実装しておいて損はないと思いますが、後者はオープンソースのライブラリを使用できれば工数を大幅に削減できるはずです。
ちょっと難しいUIを実装する時は、GoogleなりGithubなりつかって、同様なことを実装しているライブラリがないか必ず探すようにしましょう。
最近はAndroidオープンソースライブラリ徹底活用(http://www.amazon.co.jp/dp/4798040029/ref=cm_sw_r_tw_dp_IFYPsb1MYGA62)
やAndroidライブラリ実践活用[厳選111](http://www.amazon.co.jp/dp/4774161284/ref=cm_sw_r_tw_dp_KGYPsb0JBRP63)のような本も出ていますので、手元においておくといいと思います。

ただ、こういった「あのとき苦労したけど、苦労する必要がなかったのでは」的な実装をしても、自分自身では難しい実装を体験することによりスキルアップにつながりました。
今ではちょっと凝ったUIでもそれなりに実装できるようになりました。
もし工数が許すのであれば、自分で実装してしまうのも一つの選択肢かもしれません。自分で実装すれば、その部分のカスタマイズが必要があるときにすぐに対応できるという利点もあります。

結論:頑張って実装したら、その努力そのものは無駄にはならない。


以上、本日のAndroid Advent Calendarに記事でした。
お粗末様でしたm(_ _)m

2013年12月4日水曜日

ng-mtg#4 AngularJS勉強会 に行ってきました。 #ng_jp

12/3に行われたAngularJS勉強会に行ってきました。
そのメモを載せておきます。
本当は整理してからと思ったのですが、結局整理して書こうとすると何も書かずに終わってしまうので。
気が向いたらきちんとまとめます。
あと間違いがあればご指摘いただければ修正します。



ng-mtg#4 AngularJS勉強会 2013/12/03 @サイバーエージェント

# 動機
* 最近JavaScriptの勉強していて、クライアントサイドのJSライブラリを習得したかったから。
* 勉強してみてAngularJSがよさげで、さらに理解を深めようと思ったから。
* 最初は簡単だけど、ちゃんと勉強すると難しいと聞いて

# 自分の背景知識
* ドットインストール(http://dotinstall.com/lessons/basic_angularjs )
* tutorial(http://docs.angularjs.org/tutorial )
をひと通りいじってあとは適当にアプリとかつくって遊んでいる状況
本格的にアプリつくっているわけではない

# 内容
## introduction
* 金井さんから説明

## AngularJS 20min @naoya_ito
https://speakerdeck.com/naoya/angularjs-20min-number-ng-jp
初心者向けにチュートリアル的な内容。AngularJSの特徴/主な機能の説明がメイン

* AngularJSがBackbone.jsよりもgithubで★がたくさんついてる状態
* JavaScript "MVW" Framework (Model View Watever) (MV* の議論の無駄 )
* AngularJSの基本
** HTMLそのものがテンプレート
*** HTMLに ng-xxxを埋め込んで、jsがそれに対応する処理をする
*** $scopeがHTMLとapp(js)の橋渡し 
** 双方向データバインディング
** HTMLフォームを変えると$scopeのオブジェクト(app側の値)が変わる/$scopeが変わるとHTML側が変わる
** しかもリアルタイムに$scopeが変わる
* アプリがDOMの構造をしらなくてよい => HTML変更をしても動かなくなるようなことが起きづらい
* ロジックでDOMの構造を構築しないようにする
* 制約によってコードが綺麗に保たれる

* いくつかの機能
** angular-resource.js
*** サーバーサイドからデータを取得するのに使える
** フィルタがすごく簡単に書ける
** Form validation
*** 必須だとrequiredつけるとか、フォームに条件をつけてvalidation可能

* コンセプトとしてJavaScriptの構造を整理するというよりもHTMLを拡張して機能を追加している
* DIによってテストしやすい

* 雑感
** DIの仕組み
*** function()定義を文字列として扱っているから、$scopeをsとか書き換えてしまうと動かない
** JSONサーバーが後ろに控えたCRUDアプリ
** グラフィックやゲーム系が苦手
** 簡単に動かすまでは簡単だけど、本格的に学習するとコスト高め
** 制約やテストしやすさで複数人数での開発は向いてる?


## OnsenUIについて ~Angular.js+Topcoat~  Kruyさん/四方さん(アシアル株式会社)
OnsenUIがどういうものかの説明。デモ等が中心
OnsenUI => https://github.com/OnsenUI/OnsenUI

* AngularJSとTopcatを組み合わせたMobile UI
* モバイル向けのUIをHTML5で簡単につくる方法を提供したかった
** jQueryMobileだとUXがいまいち/ソースコードが冗長
* 簡単/使えるUIコンポーネント
** 独自タグをHTMLに書くだけ
** 基本的なコンポーネントがデフォルトで用意されている
* ぬるぬる動く
** CSSを利用して滑らかなアニメーション
* テーマ機能
** デザインの一括変更/Font Awesome/CSS独自カスタマイズ
* 独自タグでコンポーネントを定義して、属性でアニメーション等を設定している印象
* 今後
** Onsen UIのGUIツール「UIBuilder」の提供
** Webコンポーネントを公開・共有できるしくみ

## AngularJSを実サービスで使ってみて @sakatam
AngularJSを使った実際のプロジェクトの話
https://speakerdeck.com/sakatam/angularjs-mian-qiang-hui-number-4-shi-zhan-angularjs

* プロジェクト
** 3ヶ月
** Eコマースのリニューアル
** Mobile Firstアプローチ
** ついでにAngularJS
** うまくいった

* システム構成&人員構成
** 旧構成 => jsp/Java servlet , Legacy API(RPC), DB
** 新構成 => AngularJS APp/Node.js, Legacy API(RPC), DB
** 人員:AngularJS App => UXデザイナ2 Frontend JSエンジニア2 Backend jsエンジニア2
*** フロントエンドエンジニアがBackendも踏み込める/その逆も

* なんでAngularJS?
** backbone.js => 開発者の力量でコードの品質がばらつく等 スケールしづらい
** 柔軟性では劣る
** モジュール・ベースの開発を強制 (DI/Module・Directive)
** ビューとモデルの自動バインディングのせいでコントロールが単純化・コードのメンテナンス性が高い
** 開発がスケールし易い

* 開発フロー
** 基盤づくりに時間をかけた(3week)のが功を奏した
** チーム展開(2week)でFrontendエンジニアにしっかり慣れてもらった
*** FエンジニアはDIやモジュール志向に慣れてないため
** 開発イテレーションは一般的なウェブ開発とほとんど同じ
** テストファーストができるのがメリット (プロジェクトではUnit Testは必須にした/E2E Testはクリティカルパス確認用)

* 実戦投入次のTips
** 複雑なモデル・データの状態管理
*** モデルが複雑になるとAngularJSは管理してくれない => AngularJSの長所はシンプルなモデル
*** モデルを浅くして問題回避
** $rootScope $broadcast
*** 便利だけど使いすぎるとDIの意味がなくなるので危険
** 仮引数Minify対応の紹介
** リクエスト数の肥大化に注意する(モバイル等で)
*** ビルド時にバンドルする( webmake/angular-template)
** SEO/Crawwler対策
*** UserJSで判別してPhantomJSで対応

* ほどよい制約・モジュール化の強制
* Frontendエンジニアの底上げも


## 目指せ脱初心者!あなたの知りたかったAngularJS @agektmr
初心者が中級者になるためのセッション
AngluraJSの具体的なプラクティスの紹介(でもなんだかディレクティブの話が中心)

* Angularユーザの悩み =>ドキュメントが英語/Angular Wayがあるっぽい/日本語情報が少ない/相談相手がいない/ドキュメントがわかりにくい

* AngularJSでDOMをいじるには
** ディレクティブをつくる => ハードルが高い?
*** linkがあればDOMの操作はできる
app.directive('fileSelect',function() {
  return {
     link : function(scope, elem, attr) {  //elemはjqueryオブジェクト
        elem.bind('change', xxxx);
    }
  }
});

*** AngularJSはjqueryの機能を使える(JQliteというJQueryのLite版を持っている)
*** restrict:でタグ等を指定できる
** 独自タグを定義
<script type="text/ng-template"> でテンプレートを定義
*** templateUrlでテンプレートを指定すれば、定義したhtmlを呼び出せる

* コントローラ間で変数を跨って使う => moduleを使ってvalueに割り当てる
** デモ:http://demo.agektmr.com/flexbox/ 
* DOMの塊がオブジェクトとしてそのオブジェクトを誰が所有しているか

* Web Components
** 自分の独自のelementを作れる
* AngularはWeb Componentsをとりこもうとしている
* ディレクティブはPolymerに置き換わる
** Polymer.js (Web Componentsのは http://www.polymer-project.org/ )


## LT
メモなし

# 懇親会は体調が思わしくなかったので参加せず(残念)

# リンク
toggtter => http://togetter.com/li/598391

# 感想
* AngularJSの初心者でも勉強になった。
* ただまだまだAngularJS力が足りない
* directive周りはちゃんと勉強しようと思った。ここが使いこなせないと、ちゃんと使いこなしたことにならないと思った。



明日からもがんばろ