NilOne




中規模Androidアプリ開発の過程に生じた問題と対策の紹介




                       NilOne Ltd.
                       http://nil-one.jp/
                       contact@nil-one.com
本書の内容

 弊社(NilOne)が中規模(10人月程度)のAndroidアプリ(ソーシャルゲーム)開発を通し
 て直面した問題と、それを解決するために行った対策を紹介します。これを読んだ方が同様の
 問題に直面した際の解決の糸口になれば幸いです。

 直面した問題の発生原因は大きく分けて以下の2つですので、何れかに該当する方は本書の内
 容が参考になる可能性が高いです。
    開発対象のアプリの規模が大きくなっていったこと
    端末のローカルDB(SQLite)を活用したこと

                        h
※Androidアプリを対象にしていますが、iOSアプリであっても同様の問題に直面した場合にと
 るべき対策の方向性は同じになると思います。
※本書では行った対策の概要を示すだけに留めています。紹介しているツールの具体的な設定方
 法などは各ツールのHP等を参考にしてください。
※図を簡略化するため、端末とサーバとの通信の際に行う双方向の認証などの詳細ステップは省
 略しています。




                                              NilOne
会社紹介

社名 NilOne Ltd.
設立 2011年4月1日
代表 窪田豊
事業 iOS,Androidアプリ制作(制作の依頼を承っています)
ML contact@nil-one.com
HP http://nil-one.jp/
紹介   RadialMenuというスマートフォン向けの新しいメニューUIのデモアプリ
     (Android)を公開しました。(Google Play「RadialMenu」ページ)
                         h




                                                     NilOne
開発効率向上編

∼効率良く品質の高いアプリを開発する




                     NilOne
プロジェクトの分割

 問題
 Eclipse上に作成したのAndroidプロジェクトの規模(サイズ)が大きくなるにつれ、ビルド
 や端末への転送時間が長くなり開発効率が落ちていく。
 対策
 Androidプロジェクトをまとまった機能(画面)単位に切り出す。
 解説
 サイズが大きくなったAndroidプロジェクトをまとまった機能単位で切り出し、新たにプロ
 ジェクトを作成します(図中AppA∼AppC)。こうすることで、その時の開発対象の機能を
                         h
 保持したプロジェクトのみをビルドや転送の対象にすることが可能になり、プロジェクト全体
 の規模増大による開発効率の低下を防ぐことができます。この時、切り出し元のプロジェクト
 は各プロジェクトの共通機能置き場として使用するため、外部ライブラリ化して各プロジェク
 トから参照します。
                                              外部ライブラリ
                プロジェクト                                  共通機能は
                 を分割         各機能をプ             App      Appに集約
                             ロジェクトにし
 サイズが大                       て切り出し
きくなったタイ
 ミングで
          App                          AppA    AppB       AppC

                                                             NilOne
プロジェクトの分割

 解説(つづき)
 結合テストなどのアプリの全体の流れを確認する必要のある段階になったら、切り出したプロ
 ジェクトを全て外部ライブラリ化し、全てのプロジェクトを統合するプロジェクト(図中
 AppAll)を新たに作成してそこに集約します。

               外部ライブラリ                                              外部ライブラリ
                                                  外部ライブラ
                 App                               リ化する              App


                                                          外部ライブラリ   外部ライブラリ   外部ライブラリ

   AppA         AppB          AppC                         AppA      AppB      AppC
                                         h
                                                       全てを統合す
                                                       るプロジェクト
                                                                    AppAll
                                                           を作成




参考)
 Android Developers「Managing Projects from Eclipse with ADT」
 (Androidプロジェクトを外部ライブラリ化する方法が記載されています。)


                                                                                  NilOne
単体テスト

 問題
 開発中の機能の動作確認をするために、端末にアプリを転送しなければならないため時間が
 かかる。 単体テストでの動作確認を試みたが、Android標準の単体テストツールは端末へア
 プリを転送する必要があるため問題の解決にはならないし、Eclipse上で単体テスト用のJava
 プロジェクトを用意し実行しても、テスト対象にAndroidSDKのコードが含まれていると
 「java.lang.RuntimeException: Stub!」という例外が発生し実行できない。
 対策
 Android用単体テストツールのRobolectoricを使用してEclipse上で単体テストを行う。
 解説                        h
 AndroidSDKのコードはDalvik仮想マシンで動作させることを前提として開発されているた
 め、JVM環境で動作させようとすると上記の例外が発生してしまいます。これを解決するた
 めに、AndroidSDKのコードをインターセプトして、JVM環境でも例外が発生しないように
 するツールであるRobolectricを使用します。




                                                        NilOne
単体テスト

 解説(つづき)
 Robolectricを使用して単体テストを行うにはAndroidSDK、Robolectric、JUnitのjarにパス
 を通したJavaプロジェクト(図中AppTest)を作成し、その中に単体テスト用のコードを書き
 JUnitとして実行します。


                単体テスト用の
                             AppTest
               Javaプロジェクトを
                   作成




                                h
                              App


参考)
 Robolectric




                                                         NilOne
DIコンテナ

 問題
 開発中UIの動作確認のため、UIに対して実データを供給するコード(以降、本番用コード)と
 ダミーデータを供給するコード(以降、スタブ)の切り替えを行いたいが、切り替える箇所ごと
 にコードを修正する必要があるため時間がかかる。
 対策
 DIコンテナを使用し、本番用コードとスタブの切り替えを一箇所で行う。
 解説
 例えばUserというオブジェクトの一覧を表示するListViewを開発している場合、使用するオ
                     h
 ブジェクトに、静的に作成したダミーのUserオブジェクトと、サーバから得たデータを基に
 構築したUserオブジェクトとを、様々な場面(画面レイアウト変更時やバグ発生時など)に
 おいて切り替えたい場合があります。

                         供給
                               実データ

                                User1
            User1                           この2つを
 ListView                                  簡単に切り替え
            User2             ダミーデータ         たい

            User3             DummyUser1


                                                     NilOne
DIコンテナ

 解説(つづき)
 その場合には、RoboGuiceというAndroid用のDIコンテナを使用し、本番用コードとスタブ
 を一箇所で切り替えます。この例の場合には、データを供給するコードのインターフェースを
 定義し、その実装として本番用コードとスタブの2つを作成します。

                        データの
                       供給を担う実装
                        のインター        DataProvider
                        フェース                                    ダミーデータ

             実データを供給                                             を供給する

               する                                              DataProviderの


                                      h
                                                                 実装クラス
                         DataProviderImpl   DataProviderStub


 UIの実装はDataProviderインターフェースに対して行い、そのインターフェースに対する実
 装(DataProviderImplとDataProviderStub)の切り替えをRoboGuiceの機能を使用して
 行います。 このような設計にすることで、DataProviderImplに対する単体テストがやりや
 すくなるという大きなメリットもできます。

参考)
 Roboguice

                                                                               NilOne
ローカルDB活用編
∼サーバの運用コストを抑えつつ運用を容易にする




                          NilOne
SQLiteの活用

 問題
 サーバの運用コストが、アプリから得た収益を吸収してしまう。
 対策
 必要最低限のデータ(他のユーザと共有する必要のあるデータなど)のみサーバで管理し、
 それ以外のデータ(マスターデータやユーザデータ)は端末のローカルDBで管理すること
 で、サーバの運用コストを下げる。
 解説
 サーバの運用コストを下げるために有効なのは、端末とサーバとの通信回数と通信1回当りの
                        h
 データ量をできる限り少なくすることで、そのために端末のローカルDB(SQLiteを使用)
 を最大限に活用します。 ただ、このような構成にした場合、次ページ以降に記載したいくつ
 かの問題が発生します。

                共有データ
                 の送信
       端末                           サーバ



      マスターデータ
                            共有データ
      ユーザデータ                 の受信    共有データ




                                            NilOne
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
SQLiteの暗号化

 解説
 ここで注意が必要なのは、何かしらのORMライブラリを使用している場合で、そのライブラリ
 とSQLCipherの組み合わせが正常に動作するかを確認する必要があります。弊社の場合は、
 「ORMLite」というORMライブラリを使用していましたが、SQLCipherと組み合わせて使用
 するために「ORMLite」のソースコードを少しだけ修正する必要がありました。

参考)
 SQLCipher
 ORMLite
                      h




                                               NilOne
SQLiteファイルをサーバへ送信

 問題
 各ユーザ固有のデータ(ユーザデータ)をSQLiteで管理するようにした場合、アプリ全体の利
 用状況を把握できない。
 対策
 一定のタイミングで端末がSQLiteをサーバへ送信し、サーバはそれを集計する仕組みを作る。
 解説
 ユーザデータを管理するDBは個々の端末に存在しているため、運用者からはアプリ全体の利用
 状況を把握できません。これを解決するために、端末から一定の間隔でサーバに対してSQLite
                               h
 のファイルを送り、サーバでは受け取ったSQLiteの中身を集計する仕組みを作ります。

                                                                                                 集計

   端末       SQLite
                                                 サーバA

                      SQLite   SQLite   SQLite   SQLite      SQLite   SQLite   SQLite   SQLite




  SQLite   一定の間隔                                 サーバB
           でSQLiteを
              送信
                                                          集計データ




                                                                                                 NilOne
SQLiteファイルをサーバへ送信

 解説
 これにより、(リアルタイムではないですが)アプリ全体の利用状況は把握できます。 また、
 この対策を取ることにより、ユーザがSQLiteを何らかの原因により破損した場合に、(バック
 アップがサーバ側に保管されているため)復旧してあげるサポートをとることが出来るように
 なります。
 ※「結局、送信されたSQLiteを保管しておく領域や集計のためのサーバを用意する必要がある
 じゃないか」という意見があるかもしれませんが、少なくてもこれらのサーバが障害で動かな
 くなったとしても直接的にサービスに影響しないため、運用コストは下がります。
                    h




                                           NilOne
トランザクション

 問題
 SQLiteとサーバのデータを同時に更新する処理が途中で失敗した場合、端末(SQLite)と
 サーバ間でデータの不整合が起きてしまう。
 対策
 SQLiteとサーバの更新を1つのDBトランザクション内で行う。
 解説
 例えば複数のユーザで構成される「チーム」がある場合、あるユーザがそのチームに参加した
 という情報はユーザ自身とチームメンバーが知る必要があるため、SQLiteとサーバの両方を更
                        h
 新します。この時、SQLiteの更新は成功したがサーバの更新は失敗した場合、SQLiteではそ
 のユーザはチームに属していることになっているが、サーバではそうなっていないという不整
 合が起きてしまいます。

                            ②更新失敗
                                              端末とサーバ間
               端末                       サーバ   でデータの不整合
 ①更新成功
                                                が起きる


               SQLite
                                    ×


                                                         NilOne
トランザクション

 解説(つづき)
 これを防ぐために、サーバの更新が失敗した場合はSQLiteの更新は反映させない(ロールバッ
 ク)ようにする必要があり、これを実現するためこれら2つの処理を1つのDBトランザク
 ション内で行います。
 ここで注意が必要なのは、SQLiteの更新をサーバの更新より前に行うことです。これが逆に
 なってしまうと、サーバの更新は成功しSQLiteの更新が失敗した場合に、サーバの更新はロー
 ルバックされないため、不整合の状態が発生してしまいます。


                    h




                                           NilOne
マスターデータの更新

 問題
 端末にマスターデータがあるため、更新が難しい。
 対策
 ①アプリをアップデートする 。
 ②サーバーから間接的にマスターデータを更新する。
 解説
 ゲームのマスターデータをサーバで管理している場合は、サーバのDBを更新すれば良いです
 が、端末(SQLite)で管理している場合は①、②のどちらかの方法を行う必要があります。
                    h
 ①はマスターデータを修正する場合はアプリをアップデートするという対策ですが、マスター
 データの更新毎に、ユーザはアプリアップデートする必要が出てきてしまい、ユーザにストレ
 スを与えてしまいます。




                                           NilOne
マスターデータの更新

  解説
  ②は端末がサーバからマスターデータ更新用のデータを受信し、端末がそのデータを使用して
  マスターデータを更新するという対策です。①とは異なり、ユーザにストレスを与えずにマス
  ターデータの更新を行えますが、ある程度の開発コストを要します。

                    ①更新用デー
                    タの存在チェッ
                       ク
           端末                            サーバ
                                         更新用データ


                           h
                                         (SQL相当)

          マスターデータ

                               ②更新用データ
           ユーザデータ
                                 の受信
 ③更新用
データを使用し
てマスターデー
 タを更新



  上記の対応以外に、端末側でマスターデータとユーザデータでSQLiteのファイルを分ければ、
  マスターデータの更新はサーバからダウンロードしたマスターデータのSQLiteのファイルを更
  新するだけで済むのですが、マスターデータとユーザデータをまたがったクエリを発行できな
  くなりパフォーマンスと開発効率が悪くなるため、弊社では上記の構成を取りました。
                                                   NilOne
おわりに

以上で本書の内容は終了です。記載した内容(問題に対する対策)は、弊社が試行錯誤する過
程で見出したものですが、更によい対策があると思っているので、お気づきの方はぜひご連絡
ください。

iOSやAndroidアプリではあまり品質が高くないものが多く見られますが、その原因の1つに
スマートフォンアプリ特有の設計方法が確立されていない(情報がまり出回っていない)こと
があるのではと考え、本書を公開するに至りました。本書が少しでも品質の高いアプリ制作の
ための参考になれば幸いです。
                                  NilOne Ltd. 代表 窪田豊
                     h




                                                 NilOne

More Related Content

PPTX
Monacaで簡単スマートフォンアプリ開発体験講座
PPTX
Monacaでつくるハイブリッドアプリ
PPTX
Cordovaの最近ホットな話題と地雷をまとめて紹介
PPTX
cordova/electronの構造を知る
PPTX
HTML5ハイブリッドアプリ開発のベストプラクティス
PDF
Androidでもサクサク動くHTML5ハイブリッドアプリの作り⽅
PDF
~新しい着回しと出会おう~ 『XZ(クローゼット)』 を支える技術 -Cordova編-
PDF
クロスプラットフォーム開発入門
Monacaで簡単スマートフォンアプリ開発体験講座
Monacaでつくるハイブリッドアプリ
Cordovaの最近ホットな話題と地雷をまとめて紹介
cordova/electronの構造を知る
HTML5ハイブリッドアプリ開発のベストプラクティス
Androidでもサクサク動くHTML5ハイブリッドアプリの作り⽅
~新しい着回しと出会おう~ 『XZ(クローゼット)』 を支える技術 -Cordova編-
クロスプラットフォーム開発入門

What's hot (20)

PPTX
Cordova を使って本気で商用ハイブリッドアプリ開発をやってみた
PDF
iOS/Android/Windows クロスプラットフォーム モバイルアプリ開発
PPTX
HTML5プロフェッショナル認定試験対策講座
PPTX
CordovaでAngularJSアプリ開発
PDF
120分聞けばドヤ顔で語れる apache cordova スーパー勉強会
PPTX
HTML5×Monacaプログラミング教育事例セミナー・ワークショップ資料
PDF
WordPress APIで作るモバイルアプリ
PDF
Visual Studio 2015 を使用した Cordova アプリの開発
PDF
もっと良くなるHTMLアプリケーション設計と実装
PDF
デブサミ2015「実践!クロスプラットフォーム モバイルアプリ開発」
PPTX
ソニーでElectronアプリをリリースしてみた
PDF
kintone 連携スマホアプリの開発・配布体験
PDF
はやわかりHTML5ハイブリッドアプリ開発事情
PDF
エンタープライズ・モバイルアプリにおける ハイブリッドアプリ開発
PPTX
smartFXにおけるApache Cordovaの活用について
PDF
書籍『Monacaで学ぶはじめてのプログラミング』 講義スライド第2弾(体験版)
PDF
Onsen UI 2.0とUIライブラリの未来
PDF
PhoneGapでWebアプリをスマホアプリ化
PPTX
Cordova×業務システム:失敗しないモバイル開発の秘訣
PPTX
パララックスでレスポンシブでJ query mobileなサイトのつくりかた
Cordova を使って本気で商用ハイブリッドアプリ開発をやってみた
iOS/Android/Windows クロスプラットフォーム モバイルアプリ開発
HTML5プロフェッショナル認定試験対策講座
CordovaでAngularJSアプリ開発
120分聞けばドヤ顔で語れる apache cordova スーパー勉強会
HTML5×Monacaプログラミング教育事例セミナー・ワークショップ資料
WordPress APIで作るモバイルアプリ
Visual Studio 2015 を使用した Cordova アプリの開発
もっと良くなるHTMLアプリケーション設計と実装
デブサミ2015「実践!クロスプラットフォーム モバイルアプリ開発」
ソニーでElectronアプリをリリースしてみた
kintone 連携スマホアプリの開発・配布体験
はやわかりHTML5ハイブリッドアプリ開発事情
エンタープライズ・モバイルアプリにおける ハイブリッドアプリ開発
smartFXにおけるApache Cordovaの活用について
書籍『Monacaで学ぶはじめてのプログラミング』 講義スライド第2弾(体験版)
Onsen UI 2.0とUIライブラリの未来
PhoneGapでWebアプリをスマホアプリ化
Cordova×業務システム:失敗しないモバイル開発の秘訣
パララックスでレスポンシブでJ query mobileなサイトのつくりかた
Ad

Similar to 中規模Androidアプリ開発の過程に生じた問題と対策の紹介 (20)

PPTX
DroidKaigi アプリの内部を見る
PDF
Android Lecture #01 @PRO&BSC Inc.
PDF
OpenCVをAndroidで動かしてみた
PDF
スケーラブルで手間なく動かせる!もうすぐ 一般提供開始 Azure Database for MySQL / PostgreSQL
PPTX
UnicastWS vol.2
PPTX
MLflowで学ぶMLOpsことはじめ
PPTX
Appsody でnodejsのアプリを立ち上げよう!
PPTX
Moot2013 moca ver0.3
PPTX
dstn交流会_data_spider 3.0最新情報とデモ
PDF
Smart Store サーバーレスアーキテクチャ編
PDF
20190514 Smart Store - Azure servlerless architecture
PDF
DSL駆動によるクラウド・アプリケーション開発
PDF
LambdaとMobileの美味しいかもしれない関係
PDF
Amazon EC2 Container Service Deep dive
PDF
Intalio japan special cloud workshop
PDF
Application Deployment on AWS
PPTX
2012年1月技術ひろば
PDF
東北クラウド実践カンファレンス2011
PDF
コンテナ環境でJavaイメージを小さくする方法!
PDF
Webフロントエンド開発の最新トレンド - HTML5, モバイル, オフライン
DroidKaigi アプリの内部を見る
Android Lecture #01 @PRO&BSC Inc.
OpenCVをAndroidで動かしてみた
スケーラブルで手間なく動かせる!もうすぐ 一般提供開始 Azure Database for MySQL / PostgreSQL
UnicastWS vol.2
MLflowで学ぶMLOpsことはじめ
Appsody でnodejsのアプリを立ち上げよう!
Moot2013 moca ver0.3
dstn交流会_data_spider 3.0最新情報とデモ
Smart Store サーバーレスアーキテクチャ編
20190514 Smart Store - Azure servlerless architecture
DSL駆動によるクラウド・アプリケーション開発
LambdaとMobileの美味しいかもしれない関係
Amazon EC2 Container Service Deep dive
Intalio japan special cloud workshop
Application Deployment on AWS
2012年1月技術ひろば
東北クラウド実践カンファレンス2011
コンテナ環境でJavaイメージを小さくする方法!
Webフロントエンド開発の最新トレンド - HTML5, モバイル, オフライン
Ad

中規模Androidアプリ開発の過程に生じた問題と対策の紹介

Editor's Notes