Cat Dev It!

develop apps

Android Test Test Test

Androidで案件やってるとテスト用、本番用の設定が多々必要になります。
Cでは#ifdefとかでコードを除外でき、リバースエンジニアリングもされにくい。でもAndroidは怖いです。プリプロセッサのディレクティブが使えないのですべてソースコードに含まれます。
Javaなので仕方ないのですが逆コンパイルも簡単にできちゃいます☆(ゝω・)vキャピ
こんなのでリリースできねぇ!開発サーバーの攻撃とか休日返上になってしまう!

というわけで対処します。


  1. ソースコードで分岐
    なんかもう色々と気にしない潔い人用。わかちこわかちこ
    if (BuildConfig.DEBUG)の嵐。

  2. 設定ファイルを差し替える
    設定ファイルは差し替えればいいよ!リリースビルド前に設定差し替え!いつの日か差し替え忘れで・・・αβοοη..._φ(゚∀゚ )アヒャ

  3. 設定ファイルを差し替えるその2
    設定ファイルは差し替えればいいよ!adbで直接突っ込もう!プログラマしかいじれないブラックボックス。root端末しかダメだし、ダメダメ

  4. 設定ファイルを差し替えるその3
    BuildConfig.DEBUGでprefs.xml、prefs_test.xmlとか読み分ければいいね!
    これもapkに含まれても気にしない潔い人用。

  5. プロジェクトを分ける
    ifdefがないならプロジェクトを分ければいいじゃない。(まりーあんt
    prefs.xml以外マージしていけばめんどいけどそれなりじゃね?マージし忘れてコンフリクトとか楽しい!!!真っ赤に燃えた競合だから♪

  6. 別アプリを作る
    別アプリの設定をBuildConfig.DEBUG見て読めばいいじゃん!
    別アプリがなければ設定読めなくて例外が発生するから、別アプリのインストール必須でふとした拍子の本番設定とかも防げる!
    リリース時はフラグが降りるから当然自分のアプリの設定が読まれるよ!

いけてる方法。イケメソ。それは・・・別アプリを作る!
結構大それたように感じるし、上司からも怪訝な顔されることうけあい。もうセキュリティとかいいじゃんみたいなことに。
でも簡単なんです。SharedPreferencesで設定を読むだけ!
まあググればすぐに出るんですけど
createPackageContext(CONTEXT_IGNORE_SECURITY)
getPreferences(MODE_WORLD_READABLE|MODE_WORLD_WRITABLE)
みたいなやつです。テスト設定アプリはPreferenceActivityとかで軽く作れちゃうし。

ただし注意があります。ここからなぜかあまり情報がないので書いておきますがテストアプリと、本番アプリで設定ファイル名を変えておく必要があります。
設定ファイル名が同じだとひっそりとキャッシュされたSharedPreferencesのインスタンスが返ります。これにはなんだかとてもはまった。
明らかにテストアプリのコンテキストから取得してるのにデバッグログを見て絶望。
調べたら/(^o^)\ナンテコッタイ
設定の書き込みは本番にとかコンテキストを使い分けてやっていたからそのタイミングで先にキャッシュされてしまっていたのでしょう。
次に注意すべき点。
自身のコンテキストではないSharedPreferencesへの書き込みはミスります。
Couldn't rename file *** to backup file ***みたいなログが出る。
試しにchmodでパーミッション変えるとうまくいく。なんだよMODE_WORLD_WRITABLEって!!!ワールドイズマインじゃねえか!!!
というわけでandroid:sharedUserIdを使いましょう。
まあSharedPreferencesが楽だからこんな感じです。別アプリのデータ共有って意味ではContentProviderを使うのがベストプラクティスみたいな。

暇があればサンプルコードでも置いときます。