More Related Content
Monacaで簡単スマートフォンアプリ開発体験講座 Cordovaの最近ホットな話題と地雷をまとめて紹介 HTML5ハイブリッドアプリ開発のベストプラクティス Androidでもサクサク動くHTML5ハイブリッドアプリの作り⽅ ~新しい着回しと出会おう~ 『XZ(クローゼット)』 を支える技術 -Cordova編- What's hot (20)
Cordova を使って本気で商用ハイブリッドアプリ開発をやってみた iOS/Android/Windows クロスプラットフォーム モバイルアプリ開発 120分聞けばドヤ顔で語れる apache cordova スーパー勉強会 HTML5×Monacaプログラミング教育事例セミナー・ワークショップ資料 Visual Studio 2015 を使用した Cordova アプリの開発 デブサミ2015「実践!クロスプラットフォーム モバイルアプリ開発」 エンタープライズ・モバイルアプリにおける ハイブリッドアプリ開発 smartFXにおけるApache Cordovaの活用について 書籍『Monacaで学ぶはじめてのプログラミング』 講義スライド第2弾(体験版) Cordova×業務システム:失敗しないモバイル開発の秘訣 パララックスでレスポンシブでJ query mobileなサイトのつくりかた Similar to 中規模Androidアプリ開発の過程に生じた問題と対策の紹介 (20)
Android Lecture #01 @PRO&BSC Inc. スケーラブルで手間なく動かせる!もうすぐ 一般提供開始 Azure Database for MySQL / PostgreSQL Appsody でnodejsのアプリを立ち上げよう! dstn交流会_data_spider 3.0最新情報とデモ Smart Store サーバーレスアーキテクチャ編 20190514 Smart Store - Azure servlerless architecture LambdaとMobileの美味しいかもしれない関係 Amazon EC2 Container Service Deep dive Intalio japan special cloud workshop Application Deployment on AWS Webフロントエンド開発の最新トレンド - HTML5, モバイル, オフライン 中規模Androidアプリ開発の過程に生じた問題と対策の紹介
- 5. プロジェクトの分割
問題
Eclipse上に作成したのAndroidプロジェクトの規模(サイズ)が大きくなるにつれ、ビルド
や端末への転送時間が長くなり開発効率が落ちていく。
対策
Androidプロジェクトをまとまった機能(画面)単位に切り出す。
解説
サイズが大きくなったAndroidプロジェクトをまとまった機能単位で切り出し、新たにプロ
ジェクトを作成します(図中AppA∼AppC)。こうすることで、その時の開発対象の機能を
h
保持したプロジェクトのみをビルドや転送の対象にすることが可能になり、プロジェクト全体
の規模増大による開発効率の低下を防ぐことができます。この時、切り出し元のプロジェクト
は各プロジェクトの共通機能置き場として使用するため、外部ライブラリ化して各プロジェク
トから参照します。
外部ライブラリ
プロジェクト 共通機能は
を分割 各機能をプ App Appに集約
ロジェクトにし
サイズが大 て切り出し
きくなったタイ
ミングで
App AppA AppB AppC
NilOne
- 6. プロジェクトの分割
解説(つづき)
結合テストなどのアプリの全体の流れを確認する必要のある段階になったら、切り出したプロ
ジェクトを全て外部ライブラリ化し、全てのプロジェクトを統合するプロジェクト(図中
AppAll)を新たに作成してそこに集約します。
外部ライブラリ 外部ライブラリ
外部ライブラ
App リ化する App
外部ライブラリ 外部ライブラリ 外部ライブラリ
AppA AppB AppC AppA AppB AppC
h
全てを統合す
るプロジェクト
AppAll
を作成
参考)
Android Developers「Managing Projects from Eclipse with ADT」
(Androidプロジェクトを外部ライブラリ化する方法が記載されています。)
NilOne
- 7. 単体テスト
問題
開発中の機能の動作確認をするために、端末にアプリを転送しなければならないため時間が
かかる。 単体テストでの動作確認を試みたが、Android標準の単体テストツールは端末へア
プリを転送する必要があるため問題の解決にはならないし、Eclipse上で単体テスト用のJava
プロジェクトを用意し実行しても、テスト対象にAndroidSDKのコードが含まれていると
「java.lang.RuntimeException: Stub!」という例外が発生し実行できない。
対策
Android用単体テストツールのRobolectoricを使用してEclipse上で単体テストを行う。
解説 h
AndroidSDKのコードはDalvik仮想マシンで動作させることを前提として開発されているた
め、JVM環境で動作させようとすると上記の例外が発生してしまいます。これを解決するた
めに、AndroidSDKのコードをインターセプトして、JVM環境でも例外が発生しないように
するツールであるRobolectricを使用します。
NilOne
- 9. DIコンテナ
問題
開発中UIの動作確認のため、UIに対して実データを供給するコード(以降、本番用コード)と
ダミーデータを供給するコード(以降、スタブ)の切り替えを行いたいが、切り替える箇所ごと
にコードを修正する必要があるため時間がかかる。
対策
DIコンテナを使用し、本番用コードとスタブの切り替えを一箇所で行う。
解説
例えばUserというオブジェクトの一覧を表示するListViewを開発している場合、使用するオ
h
ブジェクトに、静的に作成したダミーのUserオブジェクトと、サーバから得たデータを基に
構築したUserオブジェクトとを、様々な場面(画面レイアウト変更時やバグ発生時など)に
おいて切り替えたい場合があります。
供給
実データ
User1
User1 この2つを
ListView 簡単に切り替え
User2 ダミーデータ たい
User3 DummyUser1
NilOne
- 10. DIコンテナ
解説(つづき)
その場合には、RoboGuiceというAndroid用のDIコンテナを使用し、本番用コードとスタブ
を一箇所で切り替えます。この例の場合には、データを供給するコードのインターフェースを
定義し、その実装として本番用コードとスタブの2つを作成します。
データの
供給を担う実装
のインター DataProvider
フェース ダミーデータ
実データを供給 を供給する
する DataProviderの
h
実装クラス
DataProviderImpl DataProviderStub
UIの実装はDataProviderインターフェースに対して行い、そのインターフェースに対する実
装(DataProviderImplとDataProviderStub)の切り替えをRoboGuiceの機能を使用して
行います。 このような設計にすることで、DataProviderImplに対する単体テストがやりや
すくなるという大きなメリットもできます。
参考)
Roboguice
NilOne
- 12. SQLiteの活用
問題
サーバの運用コストが、アプリから得た収益を吸収してしまう。
対策
必要最低限のデータ(他のユーザと共有する必要のあるデータなど)のみサーバで管理し、
それ以外のデータ(マスターデータやユーザデータ)は端末のローカルDBで管理すること
で、サーバの運用コストを下げる。
解説
サーバの運用コストを下げるために有効なのは、端末とサーバとの通信回数と通信1回当りの
h
データ量をできる限り少なくすることで、そのために端末のローカルDB(SQLiteを使用)
を最大限に活用します。 ただ、このような構成にした場合、次ページ以降に記載したいくつ
かの問題が発生します。
共有データ
の送信
端末 サーバ
マスターデータ
共有データ
ユーザデータ の受信 共有データ
NilOne
- 13. SQLiteの暗号化
問題
root化された端末を所持している悪意のあるユーザにSQLiteの内容を改ざんされる
可能性がある。
対策
SQLiteを暗号化する。
解説
アプリで使用するSQLiteは、一般の権限を持つ他のアプリやユーザ(図中一般ユーザ)からは
読み書きできないようにすることができますが、root化された端末(図中rootユーザ)におい
h
ては読み書きができてしまいます。これを防ぐために、SQLCipherという暗号化ツールを使用
してSQLiteの内容を全て暗号化します。
一般ユーザ rootユーザ 一般ユーザ rootユーザ
暗号化
le!
! ! cessib
ac ut
block block b le!
essibl
e! unr eadab
acc
S
SQLite ?SQLite?
NilOne
- 15. SQLiteファイルをサーバへ送信
問題
各ユーザ固有のデータ(ユーザデータ)をSQLiteで管理するようにした場合、アプリ全体の利
用状況を把握できない。
対策
一定のタイミングで端末がSQLiteをサーバへ送信し、サーバはそれを集計する仕組みを作る。
解説
ユーザデータを管理するDBは個々の端末に存在しているため、運用者からはアプリ全体の利用
状況を把握できません。これを解決するために、端末から一定の間隔でサーバに対してSQLite
h
のファイルを送り、サーバでは受け取ったSQLiteの中身を集計する仕組みを作ります。
集計
端末 SQLite
サーバA
SQLite SQLite SQLite SQLite SQLite SQLite SQLite SQLite
SQLite 一定の間隔 サーバB
でSQLiteを
送信
集計データ
NilOne
- 17. トランザクション
問題
SQLiteとサーバのデータを同時に更新する処理が途中で失敗した場合、端末(SQLite)と
サーバ間でデータの不整合が起きてしまう。
対策
SQLiteとサーバの更新を1つのDBトランザクション内で行う。
解説
例えば複数のユーザで構成される「チーム」がある場合、あるユーザがそのチームに参加した
という情報はユーザ自身とチームメンバーが知る必要があるため、SQLiteとサーバの両方を更
h
新します。この時、SQLiteの更新は成功したがサーバの更新は失敗した場合、SQLiteではそ
のユーザはチームに属していることになっているが、サーバではそうなっていないという不整
合が起きてしまいます。
②更新失敗
端末とサーバ間
端末 サーバ でデータの不整合
①更新成功
が起きる
SQLite
×
NilOne
- 19. マスターデータの更新
問題
端末にマスターデータがあるため、更新が難しい。
対策
①アプリをアップデートする 。
②サーバーから間接的にマスターデータを更新する。
解説
ゲームのマスターデータをサーバで管理している場合は、サーバのDBを更新すれば良いです
が、端末(SQLite)で管理している場合は①、②のどちらかの方法を行う必要があります。
h
①はマスターデータを修正する場合はアプリをアップデートするという対策ですが、マスター
データの更新毎に、ユーザはアプリアップデートする必要が出てきてしまい、ユーザにストレ
スを与えてしまいます。
NilOne
- 20. マスターデータの更新
解説
②は端末がサーバからマスターデータ更新用のデータを受信し、端末がそのデータを使用して
マスターデータを更新するという対策です。①とは異なり、ユーザにストレスを与えずにマス
ターデータの更新を行えますが、ある程度の開発コストを要します。
①更新用デー
タの存在チェッ
ク
端末 サーバ
更新用データ
h
(SQL相当)
マスターデータ
②更新用データ
ユーザデータ
の受信
③更新用
データを使用し
てマスターデー
タを更新
上記の対応以外に、端末側でマスターデータとユーザデータでSQLiteのファイルを分ければ、
マスターデータの更新はサーバからダウンロードしたマスターデータのSQLiteのファイルを更
新するだけで済むのですが、マスターデータとユーザデータをまたがったクエリを発行できな
くなりパフォーマンスと開発効率が悪くなるため、弊社では上記の構成を取りました。
NilOne