Androidオールスターズ2
Androidオールスターズ2
2016年8月7日午後1時30分 日
【満員御礼につき50席増枠★】Androidオールスターズ2 - dots. [ドッツ]
参加してきました。
メモ書き程度ですが、後日資料も公開されるとのことで楽しみにしています。
大変学びが多く、刺激のある内容でした。
次回は来年の同時期?とのことでそちらも楽しみにしています。
- Androidオールスターズ2
会場説明
- dots イベントスペース
- 開設から1年
- twitter
- ハッシュタグ eventdots
- 資料公開
- #eventdots で後日資料公開
- パネルディスカッション
- モデレータが見つからず中止
Tips 共有
Android の CI を始めよう
VASILY,堀江さん @Horie1024
CI とは?
- 継続的インテグレーション
CI を実現するための仕組み
- CI のためには
- インテグレーションを短時間でできる必要がある
- スクリプトでビルドできるようにして
- 編集の度にスクリプトを走らせる
- インテグレーションを短時間でできる必要がある
- バージョン管理システム
- Git など使用してソースコード修正を起点にインテグレーション
- ビルドスクリプト
- Android tasks の依存関係
- ./gradlew tasks --all
- Android tasks の依存関係
- Android Studio(Gradleベース) なら CI を行う準備はできている
- 最初はコンパイルだけ
- 開発への影響が少ないから
- 馴染んできたらテストなども追加していく
- CI サーバの構築
- CircleCI を例に
- 対象リポジトリを監視
- CircleCI を例に
iQon の CI 導入事例
- release branch なら fabric でテスターに
- master なら Google Play へのアップロード
- 導入
- 元はメールでの配布
- CircleCIを導入
- Android CI は難しい?
Flux de Relax :)
@ogaclejapan
Flux
- Observer パターン
why flux?
- アプリ開発でビューの状態管理が面倒
- Abema TV の機能増で必要に
Dispatcher
- Action と Store をつないでデータをストア
- 普通に書くと型変換が必要
- EventBus が良さそう
Action
- ユーザ操作でデータを取りに行く
- 取り終わったら dispatcher に
- Web, DB, Devices を外部サービスとして捉える
- 外部apiの返り値は rx に統一しておく
Store
- データ受け取るために dispatcher を監視
- データを受け取ったらStore内データを更新する
- データを更新したらビューにコールバック
- 独自に ActivityLifeCycleHook
- ライフサイクルで監視を登録削除する
- ObsevableXX の代わりに Rx を使う
- store 内でしか書き換えない、の実現のため
- Abema TV 内では検討中
- リスト更新だけは自作の量が増えるかも
View
- データ更新されたらビューで受け取る
- Store の状態に応じてViewを更新する
- Store の状態に応じて Adapter を更新する
- Action に処理を移譲する
- ビューでも Rx に
- Store が複数あり、それらの組み合わせでビュー更新という系が
Conclusion
- Pros
- view 間の依存激減
- 役割が明確なので開発者の実装が統一される
- たん方向なのでコードが追いやすい
- Cons
- シンプルな機能だと若干冗長
- 解放ミスるとメモリリーク
- 基本トライ&エラー
- Android で Flux という実装はまだない
- チーム内で統一できる設計になることが重要
- DDD が良ければそちらを導入しても
aptとKotlinでコードを(なるべく)書かないAndroid開発
@kikuchy
Kotlin の話が20分に収まらなかった! 聞きたかったら挙手!
- 想定リスナー
- 2人移譲で開発
- コード保守が大変
コードの保守
- 保守の何が大変
- 人件費
- 時間
- 気持ち的な
apt
- apt だったら一部分から使い始められる
- JSR269
- Pluggable Annotation
- Android 界隈では apt と呼ばれることが多い
- コンパイル時にアノテーションを見て何かしらの処理
- JSR269
- 使いどころ
- マッピングの手間を減らす
- 何かしらの変換対応作業
- ButterKnife
- R.id.* の View をクラスのフィールドに対応させる
- orma
- DBの行をPOJOに、カラムをフィールドに対応させる
- ButterKnife
- 何かしらの変換対応作業
- クラッシュの発生をコンパイル時に前倒しする
- 文字列でlayoutファイル名やIDを指定しているとtypoの危険性が
- コンパイルエラーとして前倒しできればすぐ気付く
- マッピングの手間を減らす
- できること
- 作例
- POJO を HashMap<String, String> に移し替える
- 作例
作ろう!
- rejsupotaro さんの
- Androidでaptのライブラリを作るときの高速道路
- ここに書かれていない Tips を紹介
Kotlin
コードの減量とKotlinの関係
- そもそもコード行数が少なければ保守コストも少なく済む
マイナー気味で減量に効果のあること
- スコープ関数
- apply, let を使うと便利なことが多い
- Class Delegation
- Effective Java で言われる継承より合成を簡単に
- ntaro さん
- Effective Java で言われる継承より合成を簡単に
- Property Delegation
- Android で頻発する遅延評価が簡単に
- KotterKnife bindView
始めよう Localization
@jfsso
Drivemode
始めよう
- これから多言語化
- どんなツールがあるか知りたい
- 翻訳の管理はどうしているか
何故多言語化?
- より多くの人にアプリを使ってもらう
Localization とは
- 地域化
- 国際化されたソフトウェアを地域の言語・習慣や文化に合わせること
- Internationalization
- ソフトを地域化しやすくする
- 多言語りソースの用意
- Formatterを使った日付や数字の使用
- 柔軟性の高いレイアウトの設計
- l10n
- i18n
国際化はどう始めればいい?
- 国際化のできる部分はどこか
- Strings
- 単純な文字列、複数形、日付時刻、数値通過、電話番号
- 画像、メディアファイル
- レイアウト
- Strings
- 言語別リソースを用意する方法
- デフォルトリソース
- 必要に応じて言語別リソースを用意
- 縦横のリソース判定より強い
- これより強いのは sim の国判定だけ
Stringリソースの用意
- ハードコードされているstringを見つける
- Analyze -> RnInspection by Name -> hardcoded strings
- システムの言語設定を English XA にする
- コンパイルタイムに変な文字列に置き換えた後、3割ぐらい長くした特殊文字
- 文字列を無理やり長くしてレイアウトの崩れも検出可能
- ここで書き換わっていないものはハードコードされている!
- コンパイルタイムに変な文字列に置き換えた後、3割ぐらい長くした特殊文字
- プレースホルダーを使いましょう
- 文字列結合しない
- 言語によって順番が変わったりする
%1$s
などプレースホルだの位置を指定可能- lint で、対象言語のプレースホルだが無ければ落とす設定可能
- 文字列結合しない
- %1$d がわかりにくい
- Phrase
- android string formatting
- lint がかからなくなってしまう
- android string formatting
- Phrase
- 複数形
- plurals を定義する
- 日付
- DateFormatを使う
getBestDateTimePattern
(API 18から)
- 18 より古い場合
- DateUtils もある
formatDateTime
,formatDateRange
- DateFormatを使う
- 通貨、数値
- NumberFormatter
- 電話番号
- PhoneNumberUtils
- API バージョンによって差がある
- PhoneNumberUtils
- テキストを含む画像
- やめましょう
- 音声・映像
- Google TTS で音声合成
- 注意
- 映像はキャプションを用意
- Google TTS で音声合成
- 柔軟性の高いレイアウト
- Text を表示する枠に余裕を持たせる
- android-autofittextview
- 多用すると重くなるかも
翻訳依頼と管理編
- 依頼する前に
- stringにコンテキスト情報を付与する
- 翻訳する必要のないものをマーク
- glossary 用意
- 翻訳の質と一貫性を保つ
- 多くの翻訳管理ツールはstring直前のコメントを参照
- translatable に false を設定
- 多くのツールで対応
- どう依頼する?
- 翻訳管理サービス
- OneSky
- おやすくてオススメ
- 画像をコンテキストに追加することも可能
- 翻訳のクラウドソーシングが可能
- 運用フロー
- 開発メンバがstringリソースを追加
- ciビルドが通れば自動翻訳管理ツールにstringを送る
- OneSky
- 翻訳クラウドソーシング
- 翻訳して欲しい言語のメニューに「翻訳に協力する」ボタンを表示
- 意外と協力してくれる
- 翻訳して欲しい言語のメニューに「翻訳に協力する」ボタンを表示
- 翻訳管理サービス
MVP と DDD
@kgmyshin
設計の話を聞く前に
- 設計の話を聞くと、不安になる
- 自分の設計が否定された気持ちに
- 今作ってるもの全部作り直さなきゃ
- 政治宗教野球設計
- 安心してください
- 前田敦子推しの話してると思って聞いてください
プログラミングにおける設計
- 一般的な設計の目的
- イメージしたものを実現するまでの見通しを立てる
- プログラミングでは
- 完成後も変化する
- どうすれば変化に強いものにできるか
複雑性と設計
- 設計規模や複雑度によって適切な設計が異なる
- patterns of enterprise application architecture
MVPとDDD
- 結論から言うとこれを選んだ
- MVC の目的
- ユーザのメンタルモデルとコンピュターのデジタルモデルに端をかける
- イメージしたものをプログラムに落とし込む手法
- MVC MVC 違い
- イベントのフローが違う
- view が必ずcontroller を通る
- activity fragment から view の生成以外を剥がす
- イベントのフローが違う
なぜ DDD か
- メンタルオデルをデジタルモデルに落とす
- 重要なのはわかった
- どうやるの?
- レイヤードなクリーンアーキテクチャを目指すと。。
- 度重なる仕様変更で辛い
- DDD を選ぶ理由
- DDDは言葉と実装を一致させる
- 例えばフィードの投稿機能
- データモデル
- 投稿を編集する、コメントを追加、コメントを削除する
- activityやfragmentに書くと。。
- ドメインモデル
- データだけでなく振る舞いもモデルに含む
- 言語と実装を一致させるためシンプル
各レイヤー
- Presentation
- どうユーザに見せるか
- application
- アプリのロジック
- domain
- ドメインのロジック
まとめ
- 設計手法コスパは複雑性に依存
- 大きければMVP DDD が適しているだろう
Android 初心者を脱するための20のチップス
@yanzm
保守性+柔軟性
- Android の新しいフレームワークが出たらスムーズに追従したり
- 今日から使えるチップス
Android のだめコード
- Java が書けてない
- Android が書けてない
Java を書くときのチップス
- アクセス修飾子
- static 修飾子
- package-private にした
- テストのため
- テストクラスを同じパッケージにおいて、呼び出すだけ
- package-private にした
- final 修飾子
- コンストラクタの中でしか値をセットしないものには final
- メソッドやクラスにつけてオーバーライドさせない、とか
- コメント
- クラスコメント
- メソッドコメント
- パブリックメソッドには必ずつける
- インターフェースのメソッドにもつける
- アノテーション
- @Nullable, @NonNull
- @WorkerThread
- Non-primitive は @Nullable を指定する
- 間違って integer じゃなくて、null 入ることあると明示
- ジェネリクス
とか
- 適切なviewを使う
- listview in listview
- RecyclerView にしましょう
- listview in listview
- View階層は浅く
- RelativeLayout の属性をこビューが使ってない
- だったら FrameLayout でいいし
- LinearLayout でテーブルっぽいレイアウト
- GridLayout 使えば
- どういうレイアウトがあるのかまず知ること
- RelativeLayout の属性をこビューが使ってない
- 関係ない属性を書かない
- FrameLayout に gravity は指定できません、とか
- View も DRY
, - タブレット対応は変わるところだけ作る
- それ以外は include しておく
- tools を使う
- tools:text
- プレビューでは出るけど実行時はでない
- tools:layout_width, tools:layout_height
- tools:visibility
- 最初 gone で始めたいけどプレビューでは見たい
- tools:context
- tools:layout
- tools:showIn
- tools:text
- Lint は友達
- abortOnError false やめて
- proguard かけよう
- あとあと対応だとどんどん対応が大変になる
- 依存ライブラリは外部モジュールで
- libs いかにja
- ディスプレイサイズはResourcesから
- DisplayMetrics
- TextUtils
- isEmpty()
- タスクは積み直せる
- TaskStackBuilder
- flag activity clear top
- singletop, new task
- TaskStackBuilder
- static 生成メソド
- intent, fragment 等はそれぞれ static メソッドで
- テスト容易
- 帰ってきたフラグメントに適切な初期値入っているか、など
- intent, fragment 等はそれぞれ static メソッドで
- フォーマットかけよう
Alt + Command + l
QA
- Lint
- warning どこまで?
- 設定ファイルを外出しして、無視していいやつとか
- CookPad が Java の設定はいいのありそう。Androidはなさそう
- CI
- Play Sore
- Gradle のプラグインでやってるけどメンテナンスされていない
- GreenHouse
- SDKアップデートへの追従
- 今は手でやっているが、
- Play Sore