http://www.slideshare.net/yanzm/droid-kaigi2015-yanzm?ref=http://www.slideshare.net/yanzm/slideshelf
Activityに書いていたものをどこに移すか?
- Fragment
- CustomView
まずは特徴を知ろう。
どれも、独自レイアウトとロジックを持てるもの。
"シングルなユーザーができることにフォーカスしたもの"
CustomView、Fragmentでできないこと全部。
"Activityのインターフェイスと振る舞いをおきかえるもの"
どちらかといえばActivity寄り。
ネットワーク、画面回転しても保持したいこと。
描画を受け持つもの。
描画、バリデーション。
- 既存View組み合わせたGroupView
- 独自ルールで配置されるGroupView
- 独自計算でサイズが決まるView
- 独自の見た目のView
Activityはだいたい何でもできる。 一番の特徴は、他の画面から呼び出せること。入り口を分けたかったらActivityを分けるしかない。 Orientationの指定できる。 Fragmentを子に持てるのはActivityだけ。 ただ、一画面に複数おくことはできない。
Fragemntは画面回転の前後でインスタンスが保持してくれる。
画面に描画を行えるのはCustomViewのみ。 CustomView以外はテストがしづらい。
実演
改修前 https://gist.github.com/yanzm/1d2fa37e2375cf4dee6f
- ViewのマニピュレーションはActivityに書かない。Viewにやらせる。
- 入力中の値の保持だとかはViewにやらせる。View.BaseSavedStateとかある
- CustomViewに独自のデータクラスを作って持たせるとget/setが楽
- ネットワーク処理やファイル処理、Preference処理は別クラスにやらせる
改修後 https://gist.github.com/yanzm/d0a759300cfa1356c0b5
- コンストラクタ
- 引数付きコンストラクタは使わない。(ドキュメントに書いてる)
- 引数なしのコンストラクタはpublicに
- 初期値設定はgetArguments()/getArguments()使う
- ActivityへのコールバックはonAttach()で
- FragmentのBackStackは難しい
- むやみに使うと危険
- FragemtnからstartActivityしないほうがいいハマる。
- Fragment in Fragment
- FinFでLoaderは使わない
- childFragementでstartActivityForResultは使わない。なぜかparentFragmentの方に値が帰ってくる
- ソースコード書くの大変→ライブラリ使うとかいいIDE使うとか
- 管理大変→git使えば
- テスト→JUnitあるでしょあと自動化
- テスト版配布→Deploygate使いましょう
「バグゼロでお願いします」 いやむりっしょ。エクセルでてんこ盛りのチェック表、エビデンスという名のスクショ・・・
小さなリファクタしてもやっぱり壊すことがある。
テストを書きましょう。 最初はテストをかく。 要件表の一番上からテストに落として行く。 そこから始められればいいのだが・・・
アプローチ。
- アプリの外部に依存する部分にDIを入れる。
- グローバル変数を取る。
- シングルトンという名のグローバル変数も取る。
- 投げっぱなしスレッドを止める。
- 最小限のリファクタリング
- ひたすらテストを書く
どうやって外部文を差し替えるか。
- DaggerとかのDIを使う。
Factoryクラス(シングルトン)をかます。 テスト時はFactoryを差し替える。
便利クラスに通信処理を固める。 テスト時はDIで偽の通信処理に差し替える。 偽の通信データは、AndroidTestのassetに入れると便利。
- ブラックボックステスト
- コンバージョンにつながる部分は重点的に書く
- テストの粒度はマチマチでもいい(やりすぎない程度で)
- JUnit4
- 実機テスト
- Espresso
- Clashliitics
- Mockito
標準で用意されているもので十分強力。
そんなものはない。
- バージョンが多様
- ベンダによる謎カスタマイズ
- カメラアプリは鬼門
- プログラマーの無知や怠慢←ここは乗り越えよう!!!!!
まずはバグに向き合うこと。 マナボでは、毎週月曜にCrashlitics
- FragmentTrasactionの取扱ミス
- 死んでるコントローラへのアクセス
- API連携ミス
- とか
本当にライフサイクルを理解しているのか、と疑うようなコードをプロも書く。
開発者向けオプション「アクティビティを保持しない」をオンにすること!!!
これで、onSaveStateとかちゃんと使うコードがかけるよ!
非同期処理は寿命が大事。
投げっぱなしにしたAsyncTaskとか、Activityより長生きする。 もともと少なくとも2~3秒で終わる処理のためのクラス。 画面回転で結果を引き継げない。画面回転するとActivityはonDestroyを迎えてしまうが、AsyncTaskがインスタンスを握っているのでGCされない。典型的なメモリリークの例。 AsyncTask継承クラスをstaticクラスにする、弱参照でActivityを掴んでおく、細かくキャンセルされているかを確認する、とかすればだいぶマシになる。
Loaderを使うという手もある。こいつは回転をしても生き残る。
ただLoaderよりEventBusの方が使われる。 オブザーバーパターンのクラスで、使い方によっては便利。(LoaderはManagerとActivityの1対1対応のためのもの)
大きく分けて、ActivityContextとApplicationContextがある。
だいたいのケースでApplicationContextが使える。
引数なしコンストラクタを使うこと。メモリ足りなくなった時はBundleにシリアライズされ、復帰時はBundelからリフレクションで展開される。
-
AndroidStudio。特に何も設定しなくてもIDEがいろいろ教えてくれる
-
困ったらShiftキー2回押し。
-
Genymotion
-
AndroidStudio用プラギンも合わせて
-
Butter Kinfe
-
フィールドとIDの対応付けや、Viewのイベント取得が簡単になる。
-
これもプラギンがあって、自動的にアノテーション付けてくれる。
-
コードがし視覚的に分かりやすくなる
-
他にはAndroidAnnotationsというのがあるが、いろいろできすぎるので、初心者には向かないかも
-
EventBus
-
任意のインスタンスに任意の通知を飛ばせる
-
データ詰め込める、スレッドも飛び越える
-
受信側が死んでてもアプリが落ちない
-
Retorofit, OkHttp, Gson
-
WebのAPIを叩いて結果を受け取るときにつかえる。
-
画像の読み込みにはpicassoが使える。
-
ORMはActiveAndroid、Realmがおすすめ
AndroidにはMVCという考え方がない。 とりあえずMVCをAndroidに取り入れる説明。
- Model ふつうのJavaクラス
- Controller Fragment(or Activity)
- View レイアウトXMLだったりViewクラスだったり
Model -> ViewはEventBusで通信する
データの保持とデータの操作メソッド。
データはControllerからこちらに追い出す。 エベント取得やViewの操作はしない。
複数の画面で使い回すものとかは、長寿のモデルに。 長寿モデルはシングルトンにしておく。
データ構造を表現するEntityは別に用意しておく。 EntityはModelで扱うListの中で使ったりする。
まずはFragmentはModelからのEventを購読する。何か飛んできたら何も考えずに画面更新するメソッド叩く。 Modelはデータが更新されたらすぐEventBusのイベントを飛ばす。
イベントは全部Controllerになげる。Viewに処理はさせない。
以前はIntentでActivityを切り替えていくものだったが、今はアプリケーションにActivityは一つ。その中でFragmentを切り替えていく。
Fragmentが太り出したら、サブコントローラーに切り出す。 普通のjavaクラスにonStartとかonResumeとかメソッドを作っておいて、Fragmentから叩かせる。
- AndroidエンジニアのためのモダンJava
- Effective Java
- AndtroidStudioのプロジェクト雛形
- 同じく自動生成されたFragment
- Googleさんのサンプル
- mixiのTrainingは最初は難しいので後回し
- 通信やSQLまわりはライブラリ使う前提で
- 端末の向きは固定で
- タブレットの2ペインレイアウトは最初はやらない
okano shinobuさん
http://www.slideshare.net/shinobuokano7/android-47395733 https://github.com/operando/DroidKaigi
今は本読まなくて良い。ドキュメントが沢山ある。 最初はクソコードを書きまくって、読みまくることが大切。 OSSのアプリのソースを読みまくると良い。 WordpressのAndroidアプリとか良い。
技術的判断が求められる立場。 そのための材料が必要。
バージョンごとの機能を理解する。 Google Play Service使う。 最新情報をキャッチアップ。
デザインを、どんなViewをつかって実装するか決める必要が有る。 とりあえずいろんなアプリをみるために、TRENDINGカテゴリのアプリを手当たり次第落として見てる。 Wishlist便利。危なそうなアプリはエミュレーターで試す。
ちょっと頭のおかしいリージョン。 技術的負債の塊だったり。
Androidソースコード検索サービスを使う。 AndroidXRef。 Firefox + Tree型タブで、メソッドの呼び出しを分かりやすく読める。
ログ大事。 logcatでログ出しまくる。 mainとsystemだけでなく、eventsとかradioあたりも見てみると良い。 adbコマンド大事。
# 入力が楽になったりするよ!
adb shell input text hogehoge@example.com
とりあえず気になるところから読んだ方が良い。
メルカリ登録コード pHe625
常に自分たちのアプリを疑う。 アプリの改善にひつような考え。
- Github
- DeployGate
- Slack
プルリクのチェックリスト。 実装に対して、チェックの範囲の認識を共有するために設けている。
PullRequestくれたら改善します!!!
最初はメルカリにもテストコードがない。
ロジックのテストからやり始めた。 一番大切なのはテストする文化。
@kmt_t
Android RunTimeの略。 KitkatまではDalvikだった。LolipopからARTになる。
Dalvikから完全書き換え。 CからC++11になってる。 JITコンパイラからAOTコンパイラになった。(インストール時にコンパイルするようになってる) ガベージコレクションが改善された。 64bitCPU対応。
OATとdexの二つ。
OATファイルは、AOTコンパイラが吐き出す機械語のファイル。 DEXはOATに埋め込まれる。メタデータなんかはそのままdexから使われる。
ELF形式で書かれている。OATは共有ライブラリ。 リンカとローダはLinuxのものを使わずに独自のものが使われている。
共有ライブラリではセクションが重要
だいたいLinuxのセクションと同じだが、ART独自のデータが含まれていたり、ART独自のセクションがあったりする。
DEXファイルとガイド情報
イメージファイルの再配置情報
イメージファイルはランダムにメモリに配置される。 このランダマイズはわざと行われている。多分セキュリティ対策。
Quickコンパイラ以外のコンパイラが消えた。
DalvikのJITコンパイラベースのコンパイラ
JITコンパイラより早い。 時間のかかる最適化が可能。
ART固有の最適化が可能。LLVMを使っていないので、LLVMで最適化できない部分がどうにかできてる。
wasabeefさん
どう考えてもBitmapは怖い OutOfMemoryErrorェ…
画像扱うAPI。 Factoryでオブジェクト生成。
4.0+ならwebp画像も使える。
- inJustDecodeBounds 画像のサイズだけ先に取得するときなど
- inSizeSample BitmapにFilterをかけるときにとても有効。
- inPreferredConfig 読み込むフォーマット
- ARGB_8888
- ARGB_4444 API13以降でdeplecated
- RGB_545 AlphaがないRGB。Alphaがない画像に使えばメモリを節約できる
- ALPHA_8 アルファ値のみとるときにつかったり。シャドーとして使いたいときとか。
Square謹製ライブラリ。
TransformationとかCachingとかLoaderもセット。べんり。
.fit()
とかのメソッドを使うと、ビューのサイズでBitmapを作ってくれるのでメモリが節約できる。
生Bitmapを取り出すことができる。
アニメGifやビデオも扱える。 サムネイルという機能で表示の体感速度が速くなってよい。
生Bitmapを取り出すときにサイズ指定が必要なのでそこは面倒。
ブラーかけるのに便利。
GPUで画像処理させるライブラリ。 CAがホストしてる。
XMLでトランスフォームの指定とかかける。 ただ、widthとheightの値を自分で指定しないといけない。warp_contentとかできない。
android:largeHeap="true"
http://www.slideshare.net/MakotoYamazaki/20150425-droidkaigi-gradle zaki50さん
汎用ビルドツール。 依存管理、マルチプロジェクトサポート。
2年くらい前からAndroidはGradleでのビルドを前提としたプロジェクトになった。
谷口岳さん TaoRiskFinderとか作ってる。
資料 http://www.taosoftware.co.jp/blog/2015/04/cf5c5d90.html
セキュリティホールがあるアプリを作らないためにはどうしたらいいのか。
日本語で読めるのは2冊だけ。
- AndroidSecurity
- Androidアプリのセキュア設計・セキュアコーディングガイド(PDF、無料)
IPAが出してるAnCoLeも良い。 自習用アプリケーション、EclipseプラギンなのでMacでも動く。
https://www.ipa.go.jp/security/vuln/ancole/
自分のアプリデータが他のアプリから見えてしまう。
Activityの乗っ取りが生じる可能性がある。
ConponentProviderのアクセス制限設定、昔のAndroidではデフォルトで公開になっていた。
コンポーネントは外部非公開にすること export = false
テスト時にオレオレ証明書使うことは多い。 オレオレ証明書だとSSL使用時に例外が出るので、それを無視するコードにしておいて、本番になっても直すの忘れてたりして脆弱性を生むことがある。
マルウェアと間違えられたりする。 外部ライブラリが悪さして、勝手に電話帳取り出したりすることがあるかも。 不必要なパーミッションは与えない。
GPL汚染とかのこと。
自分で公開するときはライセンスを明らかにしておきましょう。
この前のAFNetworksとか。 ちょっと前だとOpenSSLとか。 第三者モジュールの脆弱性は、そのままアプリケーションの脆弱性になる。
広告モジュールとかの中でも悪質なものは、勝手に電話帳を参照したりしてるものがある。 電話帳と、ならくても電話番号やANDORID_IDとかを送信していることは多い。 海外の広告モジュールは特に注意。
ライブラリがどんなデータを取っているのか、ドキュメント化されてないことが多い。 プライバシーポリシー描きづらい。
何の個人情報を取得しているのか、きちんとドキュメント化しておくのが良い。
- プライバシーポリシードキュメントの作成
- 重要なデータ取得時はユーザーに許可を求める
ただし、インストール時に出す権限を求めるダイアログはユーザーの同意取得のためのダイアログではないので注意。
法律云々よりも、自分の親や子供が安心して使えるということを考えると良い。
Nkznさん
http://www.slideshare.net/Nkzn/ss-47398311
通信網も何もない時にも使えるようにするには? Gmailでも使われているような同期の仕組みはSDKにあるのだが。
マスターテーブルとユーザーテーブルがあるタイプのアプリ。
SyncAdapter
というのがAPI lv5から入っている。
ボイラープレートがめんどくさいが、お手本があればなんとかなるレベル。
有名になったのはGoogle I/O 2013あたり。でも出てたのは2009年。
SyncAdapterの使い方は、mixiのAndroidTrainingみればわかる。
- 50 Android Hacksのサンプルコード
- Evernote Synchronizeation via EDAM
- Full Sync…依存関係だとかは保証できる。ネットワーク負荷は重くなる
- Incremental Sync…クライアントが持っているデータ量をサーバに申告し、足りない分だけ送ってもらう
差分の請求は、最終同期時刻を覚えておいて、DBのmodified_atを見てデータを取り出すとかする。
- CLEAN サーバから受け取ったまま
- ADD サーバにないデータ
- MOD サーバから受け取ったものを変更した
- DELETE サーバにあるものを消した
- とりあえずデータ取ってくる
- サーバで削除されていたらクライアントでも削除
- サーバで更新されていたものもクライアントで更新
- ADD, MOD, DELETEされたデータをサーバに飛ばす
- フラグをCLEANにし、最終同期時刻を記録
サーバーとクライアントでデータが食い違った場合。
とりうる対応策
- 常にサーバが勝つ
- 常にクライアントが勝つ(アグリノートはこれ)
- クライアント側でマージしてからサーバに送る(Evernoteはこれ)
開発時は表を作って、開発者同士ですり合わせをした。
- 作りたくないけどライフサイクル絡むと誘惑に負ける
- 5段階extends見たら使いたくなくなった
- 人によって「使っていい人」「使っちゃいけない人」でわける
- 規約で縛れればOK
- is-a関係ができる場合のみ。昨日の共通化が目的ならdelegateするのが良い。
あんまりいない
- マテリアルデザインのAlertDialogつらいので入れて
- PreferenceActivityとPreferenceFragment(似た者同士)が併用できないのどうにかして
- マテリアルデザイン系だと、PolymerにはあるけどSupport Libraryにないのがあったりするので、入れてもらえると嬉しい。
- リリース予定がわかるだけで心が安らかになるとおもう
ひだかさんのABCのアプリを引っ張ってきて、三日くらいで作られた。
Deploygateでみんなで配信。 PR出しまくり。
アプリ出したかったのは、アンケートに答えやすくしたかったから。 QRコードとったり、短縮URL打つのはだるい。
AndroidのBTLEは闇。 Wearはけっこうみんな持ってる。
- リニューアルの際に4.0以上にした
- 2.3はそろそろ切りたい
- ICS以上がいいなぁ
- 新規で作るなら、API13 (4.0.3)以上
- 2.3問題は大きい。アップデートで切るのは経営判断なのでつらい