Marshmallowでアプリをテストするときのこと

Marshmallowでアプリをテストするときのこと

By Android Developers Blog

スクラムエンジニアリンググループの片渕です。

Google I/O 2015Android M Developer Preview(Marshmallow)が発表されてから数ヶ月が経ちました。

新型のNexus5が発表されるという情報もあり、Marshmallowがユーザーの手に届く日は遠くなさそうです。

開発者としては、新機能にワクワクする一方でアプリが不具合を出したりクラッシュしないかというのが最も気にかかる所だと思います。

という事で今回は、私が担当しているアプリをMarshmallowで動作確認した際の知見を共有できればと思います。

新OSへの対応というのは通常、deprecatedになったAPIを消したり新規に追加されたAPIを呼ぶ様に修正するというのが正規のアプローチですが、現実問題としてプロダクトの状況によってはそこまでパワーを割けない場合もあります。そうした場合に「とりあえず」凌ぐ方法も紹介しています。

前提として、Android DevelopersにTesting Guideが公開されていますので、正確で詳細な情報を知りたい方はこちらを参照してください。

また、本情報は2015/09/27時点で最新のSDK preview3の仕様に基づくものです。

Permissions

今回最もドラスティックな変更として注目を集めているRuntime Permissionsですが、Google Playからインストール時に一括でパーミッションの許可を求める方式から、アプリ実行時に許可を求める方式へと変更になりました。

詳細について知りたい方はAndroid Developersか、日本語の資料だと以下のスライドに詳しくまとまっています。

Marshmallowではアプリの設定画面からいつでもパーミッションをオフにする事ができる為、パーミッションを使う処理を正しく制御しないとクラッシュの原因に成り得ます(公式にはthe method returns an empty data setと書いてありますが、実際に実行時例外を吐くような物もありました)。

targetSdkVersionが23を下回っている場合も、Google Playからインストール時に一括で権限を確認する挙動は従来と変わらないものの、設定画面から権限をオフにできてしまうので無関係というわけにはいきません。

テスト

  • 自分のアプリが対応が必要なパーミッションを利用しているか確認する
    • Android developersPermissions and permission groupsという表にまとまっています。
    • 拙作のm-permissions-checkerを利用する事で検査を自動化できます。
    • 上記以外にも、protectionLevelがdangerousなカスタムパーミッションに関しては対象となるようです。
  • 以下のadbコマンドを用いるか、設定画面から権限をオフにした時にアプリの挙動がおかしくならないか確認する

対応

Must

  • support v4 libraryのバージョンを23.0.0以上にアップデートする
  • 対象の処理をパーミッションをチェックするコードで囲む
    • 最小限な対応としては、処理を呼び出す前に PermissionChecker.checkSelfPermission でチェックして権限がオフの場合はToastで警告を出すという簡易なものでも良いと思います。

Option

  • targetSdkVersionを23にする
  • 対象の処理をパーミッションをチェックするコードで囲む
    • ハンドリングするコードを書く場合は、以下を参考にしてください。例はAcitivtyの想定ですが、Fragmentの場合は微妙に違うので適宜読み替えてください。より詳細な実装はgooglesamples/android-RuntimePermissionsを参考にしてください。

ちなみに、上記の様なボイラープレートを書くのは非常に面倒なので自動生成するライブラリを用意しました。

ぜひご検討ください。

Doze and App Standby

バッテリーの延命策として、DozeというシステムのスリープモードとApp Standbyというアプリのスリープモードがそれぞれ追加されました。

明記はされていませんが、端末やアプリを一定期間触っていないとそれぞれの状態に突入する様です。

Doze

以下のadbコマンドで端末をDozeモードにする事ができます。

端末がDozeモードを抜けた際に、アプリが問題なく動作するかを確認します。

Android Developersには以下の挙動が制限されると書いてあるので、特に以下の観点に注意しましょう。

  • ネットワークアクセスの遮断(GCMのhigh priorityを受信した場合を除く)
  • PowerManager.WakeLockは無視される
  • AlarmManagersetsetExactは保留される
    • 対応したい場合はsetAndAllowWhileIdlesetExactAndAllowWhileIdleを使う
  • Wi-fiスキャンは実行されない
  • SyncAdapterの同期やJobSchedularのタスクは保留される
    • Dozeモードを抜けた際に一気に実行される様です。

実際に私が担当しているアプリでは、NotificationをAlarmManagerで設定している箇所があったのでMarshmallowの際は該当するメソッドを呼ぶような修正を加えました。

App Standby

以下のadbコマンドでアプリをstandbyモードから開放される過程を再現できます。

Dozeモードと同様に、アプリが問題なく動作するかをチェックします。

特にNotificationやバックグラウンドのジョブがこれまで通り動作するかに注意します。

Auto Backup

Auto Backupとは、アプリのデータをGoogle Driveに暗号化してバックアップしてくれる機能です。

2.2より追加されていたBackup Serviceとは違い、特別な実装をしなくても全アプリが対象となります。

Auto Backupでは、以下のケースを除いて全ての永続化したデータがバックアップ対象になります。

  • getCacheDir()メソッドとgetCodeCacheDir()メソッドに参照されるディレクトリ内のファイル
  • getExternalFilesDir()メソッドに参照されるディレクトリ内以外の外部ストレージ内のファイル
  • getNoBackupFilesDir()メソッドに参照されるディレクトリ内のファイル

サービスの認証情報やアクセストークン等、複数端末で利用されると都合が悪いものが存在するかを確認してください。

Android Developersには、既知の問題としてGCMのregistration IDをバックアップ対象としない様に注意書きがあります。

テスト

以下のadbコマンドでバックアップを実行する事ができます。

対応

  • targetSdkVersionを23にあげる
  • android:fullBackupContent属性を指定する

android:fullBackupContentはtargetSdkVersionが23以上でないと使えないので、23にはまだできないけど不具合は出したくない、という場合はandorid:allowBackUp属性をfalseにしておくのが無難そうです。

私がテストをしていた際は、復元直後の起動時のみアプリで定義したカスタムApplicationクラスが呼ばれず、アプリがクラッシュするというバグに遭遇しissueを上げたのですが、別issueにて解決が報告されていました。

TIPS: Apache HTTP Client

SDKのバージョンを23に上げようとした時にぶつかる最大の問題が、Apache HTTP ClientのFrameworkからの削除です。

22でdeprecatedになったのも束の間、23ではその存在自体が消滅しています。

その為、アプリ内でApache Clientを利用している箇所は全てコンパイルエラーになります。

build.gradleに以下の記述を追加すればとりあえずは動きますが、早めの移行を検討した方が良いでしょう。

HTTP及びWeb API Clientの選定は以前として難しい状況にあり、以下のスライドを参考にしながら決めていくのが良さそうです。

Android標準のHTTP ClientはHttpUrlConnection、Web API ClientはVolleyがAOSPにバンドルされていますが、HttpUrlConnectionは実装を委譲しているOkHttpのキャッシュにバグがある事、Volleyは諸々の問題やマイルストーンが不透明な事を踏まえると、OkHttpとRetrofitの採用が良さそうだと感じています。

特にRetrofitは2.0のリリースが予定されており、Callアダプタの追加やリクエストキャンセルの実装、レスポンスオブジェクトの改善が行われている為大いに期待できそうです。

最後に

今回は変更の中でも特に影響度の高い部分に関してテストした知見を共有させて頂きました。

より詳細な変更はBehavior Changesを参照してください。

また、Direct Share指紋認証等新機能の対応に関しては触れませんでしたが、気になる方はAPI overviewSamplesを覗いてみてください。