Multiple APKサポートを訳してみたよ

2011/7/28 13798hit

Multiple APKサポートを訳してみたよ
Androidマーケットに加わった新しいサービスでユーザーの機器に応じて複数のAPKを1つのアプリとして利用出来る機能。
ざっくり趣旨を抜粋すると、
Androidのバージョンあるいは画面サイズ、解像度、OpenGLのテクスチャーサポートに応じて複数のAPKを1つのアプリのように見せることが出来る。
ただし、弊害として管理が超面倒になるので、極力使わないこと、
そして使わないためのアイデアが最後にちょっと記載されています。

原文

Multiple APKサポート

MultipleAPKサポートは異なる構成のデバイス向けに異なるAPKを公開することが出来るAndroid Marketの機能です。

各APKはアプリケーション内で完全に独立したバージョンです。
しかし、AndroidMarket上で同じアプリケーションリストを共有します。
パッケージ名を同じにして、同一署名である必要があります。
あなたのアプリケーションが1つのAPKでは全てのデバイスに最適に振る舞えない場合にこの機能は役立ちます。

Androidには様々な特徴を持つデバイスがありますが、できるだけ多くのデバイスでアプリケーションを利用出来るようにすることは成功のために大切な事です。
Androidアプリケーションは通常1つのAPKが大部分の互換性を持つデバイス上で動きます。
異なる構成(スクリーンサイズやレイアウトなど)のために異なるリソースを提供し、システムは実行時にデバイスに最適なリソースを選びます。

稀なケースですが、一つのAPKで全ての機器構成をサポートするには代わりのリソースがAPKを肥大化(50MB以上)させたり、その他の技術的な理由が1つのAPKで全ての機器構成に対応するのを困難とさせます。
私たちはできるだけ多くの機器構成をサポートする1つのAPKを開発し、公開するのを推奨しますが、それが出来ないことがあります。
できるだけ多くの装置を受け入れるアプリケーションを公開できるように、AndroidMarket上の同じアプリケーションリストで複数のAPKを公開することが出来ます。
AndroidMarketは各APKのManifestファイルで宣言する構成サポートに基づき、適切なデバイスにむけて各APKを提供します。
MultipleAPKであなたのアプリケーションを公開することで以下のことが可能です。
・OpenGLのテクスチャー圧縮フォーマットのサポートごとに異なるAPKを提供する
・ディスプレイの構成ごとに異なるAPKを提供する。
・Androidのバージョンごとに異なるAPKを提供する。
現時点においては、これらのみが複数のAPKを公開するためにAndroidMarketがサポートする構成の種類です。

ノート:普通、MultipleAPKを使うのは、APKがあまりに大きい(50MB以上)場合だけです。
1つのAPKで複数の異なる構成の機器をサポートするのは常にベストプラクティスです。
なぜなら、アプリケーションのアップデート経路がユーザーに取ってシンプルでクリアになります。
加えてあなたの生活をシンプルにします。
MultipleAPKを公開する前に他の選択肢を考慮するために、「1つのAPKを使用する」を読んでください。

パブリッシャーの概念

AndroidMarket上でMultipleAPKを公開する前に、
Androidarketのパブリッシャーがどのように働くかに関していくつかの概念を理解しなければいけません。

アクティブなAPK

アプリケーションを公開する前に(1つのAPKを使うかMultipleAPKを使うかにかかわらず)APKファイルタブからAPKをアクティブにさせなければいけません。
APKをアクティブにすると、ActiveAPKsのリストへ移動します。

シンプルモードとアドバンスモード

APKを管理するためにAndroid Marketの公開サイトは二つのモードを提供します。
APKファイルタブの右上にあるリンクをクリックすることで切り替えることが出来ます。
シンプルモードは1つのAPKを用いてアプリケーションを公開する従来の方法です。
1つのAPKだけをアクティブにすることが出来ます。
新しいAPKをアップロードする場合、アクティブをクリックすると現在アクティブなAPKは非アクティブな状態となります。(新しいAPKを配布するためにSaveをクリックしなければなりません)。
アドバンスモードは異なる構成の機器ごとに複数のAPKをアクティブにして公開することが出来ます。
しかし、APKを起動させて良いか決定するAPKのマニフェストに対していくつかの制限があります。
この制限に違反するとエラーまたは警告が発生します。
それがエラーであれば、問題を解決するまでAPKを公開することができなくなります。
それが警告であれば、APKを公開できますが機器構成に対してどのAPKが利用されるか予想外の事が起きるかもしれません。
それらの規則は下記に表示されます。

MultipleAPKがどのように動くか

AndroidMarket上でMultipleAPKを使うコンセプトは、ただ1つのエントリーがAndroidMarketにあるということです。
しかし、異なる構成の機器は別のAPKをダウンロードするかもしれません。
これは以下のことを意味します。
同一の製品の詳細(説明、アイコン、画面イメージ)を持ちます。
同一の価格を請求する必要があります。
全てのユーザーは異なるバージョンに戸惑わないようにタブレット用、電話用など1つのバージョンだけが見えます。
たとえ異なるデバイス向けのAPKであっても、全てのユーザーレビューは1つのアプリケーションリストに表示されます。
異なるバージョンのAndroid向けに複数のAPKを発表した場合、
ユーザーが異なるAndroidへのアップデート通知を受けた時に、Android Marketはより新しいバージョン向けに設計されたアプリケーションのAPKへ更新します。
1つのAPKを使った場合のアップデートと同じように、アプリケーションに関するあらゆるシステムデータは保持されます。
前述のとおりMultiple APKを公開するには、アプリケーションのAPKファイルタブでアドバンスモードを有効にしなければいけません。
アドバンスモードを一度アクティブにすると、MultipleAPKをアップロードし、アクティブに出来ます。
以下の章ではそれらがどのように働くかについての詳細を記述します。

サポートするフィルター

どのガジェットがどのAPKを使うかは、各々のAPKのManifestファイルにあるAndroidMarketフィルターで決定されます。
しかし、機器の特徴については以下のフィルターのみをサポートします。

・OpenGL テクスチャーの圧縮フォーマット
これはmanifestファイルのsupports-gl-textureエレメントで指定される要素です。
例えばゲーム開発者はOpenGL ESを使用するときATIテクスチャー圧縮とPowerVRテクスチャー圧縮ごとに1つのAPKを提供することが出来ます。

・画面サイズ(オプションとしてスクリーン密度)
これはmanifestファイルのsupports-screensやcompatible-screensに基づきます。
両方の要素を必ず使用すべきというわけではありません。
可能な場合はsupports-screensだけを使ってください。
例えばsmallとnormalの画面をサポートするAPKとxlargeの画面をサポートする別のAPKを公開することが出来ます。
ノート:1つのAPKで全てのスクリーン構成をサポートしたいという要望にAndroidシステムは強力なサポートを提供しています
可能なかぎり複数のAPKsを作ることを避けるべきです。
アプリケーションが柔軟に、1つのAPKですべてのスクリーン構成に適用することが出来るようにSupporting Multiple Screensのガイドを読んでください。

注意:特にそれらを宣言しなければ、全てのスクリーンサイズにおいてsuppports-screens elementはtrueです。
しかし、Android2.3(API level9)においてxlargeScreensが追加され、
minSdkVersionまたはandroid : targetSdkVersionに9以上がセットされない場合falseがデフォルトでセットされます。
注意:supports - screensとcompatible -screensの両方をmanifestファイルに組み込むべきではありません。
それらの不一致のためにエラーが発生する可能性を増やすことになります。
どちらを使うべきかについては Distributing to Specific Screens.を読んでください。
もし、両方とも使うことがさけられない場合falseが優先となります。

・API level
これはmanifestファイルのuser-sdkに基づきます。
android:minSdkVersionとandroid:maxSdkVersionで異なるAPIレベルをサポートできます。
例えばAPIレベル4から利用出来るAPIのみを使用しているAPIレベル4〜7(Android1.6〜2.1)をサポートするAPKとAPIレベル8(Android2.2以上)のAPIを使用するもうひとつのAPKを使用できます。
注意:複数のAPKとより高いAndroidによるAPKを識別するためにminSdkVersionはversionCode以上の値を持つ必要があります。
2つのAPKが異なるAPKのフィルターで装置がサポートされる場合、これもやはりTrueです。
装置がシステムアップデートを受けるとき、app version codeが増加するので、Android marketが最新のアプリケーションを提供することを確実にします。
これらの必須条件はmultipleAPKのルールで記載されます。
通常、android:maxSdkVersionを使うことを避けなければなりません。
公的なAPIでアプリケーションを正しく開発した場合、それらはAndroidの将来的なバージョンと互換性を持ちます。
より高いAPIレベルのために異なるAPKを発表したい場合、最大のバージョンを指定する必要はなくて、一つのAPKはminSdkVersionに4を指定し、APIレベル8以上向けのもうひとつのAPKには8を指定すればいいからです。

それ以外のAndroidマーケットフィルター manifestによって異なるAPKを提供することは出来ません。
例えば、uses-configurationによって異なるAPKを提供することは出来ません。

multipleAPKのルール

アドバンスモードを有効にしMultipleAPKをリリース可能にする前に、あなたはMultipleAPKがどのように働くのか以下のルールを理解する必要があります。
同じアプリケーションとして公開される全てのAPKは同じパッケージ名で同じ証明書キーで署名されていないければいけません。
各APKはandroid:versionCodeに記載するバージョンが異なる値でなければいけません。
各APKは別のAPKでサポートする機器構成と完全に一致してはいけません。
つまり、各APKはMultipleAPKでサポートされたMarketフィルター(上記)のうち少なくとも一つは異なる値を宣言する必要があります。
通常、特定の特徴(例えばテクスチャー圧縮フォーマットへのサポート)に基づくAPKを区別します。
このように各APKは異なる装置のサポートを宣言します。

しかし、複数のAPKのサポートが一部重なることはOKです。
2つのAPKが重なった場合、その共通部分に入る機器はより新しいversion codeのAPKを使用します。
version codeを低くアップデートすることは出来ません。

例えば、小さなスクリーンサイズのためにアクティブなAPKをアクティブにする場合
version code0400を通常向けに公開し、
version code0300を同じサイズのために公開しようとすると、
前のAPKユーザーがアプリケーションをアップデートできなくなるためエラーとなります。
より高いAPIレベルを必要とするAPKにはより高いversion codeが必要です。
これはAPIレベルのサポートだけに基づく場合、あるいは、APKのフィルターにおいて共通部分に入る場合に該当します。
Android Market上のAPKは現在インストール済みのAPKよりversion codeが高い場合だけアップデートを受け取るのでこれは重要です。
より高いAPIレベル向けのAPKほどversion codeが増加することにより、機器がシステムアップデートを受け、より新しいプラットフォーム向けのAPKが使用できるようなった場合に新しいアプリケーションを受け取ることを確実にします。

ノート:version codeの増加するサイズは無関係です。
単に、より高いAPIレベルをサポートするバージョンでversion codeが大きい必要があるだけです。
簡単な例:
APIレベル4以上(Android1.6以上)のためにアップロードしたAPKに0400にバージョンコードがあるならAPIレベル8以上(Android2.2以上)のAPKは0401より大きい必要があります。
この場合、APIレベルが唯一のフィルターですので、version codeは各APKに対するAPIレベルのサポートで相関関係が継続されなければいけません。
それによって、ユーザーはシステムアップデートによって最新版を得ることが出来ます。
訳注;ただし後述の理由に付きお互いのバージョンは大きく離しておくことが推奨される

もし、APIレベル4以上のsmallからlargeスクリーンをサポートする第一のAPKと
APIレベル8以上のlargeからxlargeスクリーンをサポートする第二のAPKが有った場合、
APIレベルのフィルタは各APKを識別するのに使用されますが、スクリーンサイズが重なる(両方のAPKはlargeスクリーンをサポートできる)ので、バージョンコードを適切に付与する必要があります。
APIレベル8にシステムアップデートを受けたlargeスクリーンを持つ装置が第二のAPKを受け取ることを確実にします。
もし、APIレベル4以上のsmallからnormalスクリーンをサポートする第一のAPKと
APIレベル8以上のlargeからxlargeスクリーンをサポートする第二のAPKが有った場合、
これら2つのAPKを動かせる装置がないので低いAPIlevel向けのAPKに対して高いAPIlevel向けのAPKのversion codeを高く設定する必要はありません。

APKをアクティブにする時上記のルールに基づくエラーが解決するまでアプリケーションを公開することは出来ません。
APKをアクティブにする時エラーではなく警告に終わる他の競合があります。
警告は以下に起因して発生します。
APKのサポート範囲を狭め、他のAPKでもサポートされずそれによってサポートから外れるデバイスがある場合。
例えばAPKが現在smallからnormalスクリーンをサポートしていて、それをnormalスクリーンのみのサポートに変更するとき、デバイスのサポートは縮小され、いくつかのデバイスからはAndroid Marketで表示されなくなります。
以前サポートされたデバイスがサポートされるようにnoralスクリーンをサポートするAPKを加えることでこれを解決できます。
二つのAPKに共通部分があるとき
例えば一つのAPKがlargeからxlargeスクリーンをサポートして、もうひとつのAPKがlargeからxlargeをサポートする場合、サポートに共通部分があります。
これを解決しない場合、両方のAPKが使えるlargeスクリーンのデバイスはversion codeが大きいAPKが使用されます。
このような衝突が起こるとき、警告メッセージが表示されますが、アプリケーションを公開することは出来ます。

Multiple APKを作る

MultipleAPKを作ることを決めたなら、複数のAPKを適切に開発できるように別々のAndroidプロジェクトを作る必要があるでしょう。
単に既存のプロジェクトを元に新しい名前を与えることでそれは可能です。
(あるいはあなたのビルドシステムは異なるテクスチャーを出力できるかもしれません)
チップ:アプリケーションコードの多大なる重複を避ける方法としてライブラリプロジェクトを使うことがあります。
ライブラリプロジェクトは共有のコードとリソースを持ちます。そしてそれを実際のアプリケーションプロジェクトにインクルード出来ます。

それぞれのAPKに掛る規制を名前と紐付けることは対象を簡単に特定できるので良い手段です。
例えばHelloWorld_8はAPIレベル8以上のために設計されるアプリケーションの良い名前です。
ノート:同じアプリケーションのために発表する全てのAPKは同じパッケージ名で同じ証明書キーで署名されていなければいけません。
MutipleAPKのために、各ルールを確実に理解してください。

Version codeの割り当て

各APKユニークなandroid:versionCodeがなければいけません。
場合によっては、特定の順序(各APKがサポートする構成により)で定められる必要があるためversion codeを割り当てることに慎重になるはずです。

version codeのつけ方
より高いAPIレベルを必要とするAPKには高いversion codeが必要です。
例えば異なるAPIレベルをサポートするために2つのAPKをつくるなら、より高いAPIレベルのためのAPKにはより高いversion codeが必要です。
装置が、より高いAPIレベルのためのAPKをインストール出来るようになるシステムアップデートを受け取ったときに、APKのアップデートを確実にします。
この必要条件が当てはまる方法の詳細は上記multipleAPKのルールを参照してください。

ユーザーが異なるAPKの共通部分をサポートするために、バージョンコードのつけ方が今後どのような影響を与えるか考える必要があります。
例えば異なるスクリーンサイズによって異なるAPKを作る場合、
smallからnormalとlargeからxlargeのAPKが将来
一つ目がsmallのみとnormalからxlargeのAPKに変わることを予見できません。
このような場合large-xlargeはより高いversion codeを割り振る必要があります。

そのようにAPKから現在のデバイスをサポートする新しいAPKまでversion codeが増加するのnormalサイズのガジェットは適切に最新版を取得できます。
また、異なるOpenGLテクスチャー圧縮フォーマットに対するサポートに基づいてAPKを分けるときは、
多くのデバイスが複数のフォーマットをサポートしていることを考慮してください。
複数のAPKに該当する装置は大きなversion codeのAPKを使用するので、好ましい圧縮フォーマットを使用するAPKほど高いversion codeとなるようにする必要があります。

例えばPVRTC、ATTICとETC1圧縮フォーマットを使っている異なるAPKが有り、正確にこの優先順位でフォーマットを選ぶのであれば、PVRTCは最高のversion codeを、ATTICはそれ以下で、ETC1は最小のVersion codeを割り振る必要があります。
デバイスがPVRTCとETC1をサポートする場合、最高のバージョンが使えるのでPVRTCのAPKを受信します。

バージョンコードスキーマの使用
その他、例えば1つのAPKだけのバグを修正し、他のAPKを更新する必要がないとき、APKのversion codeが別のAPKの影響を受けないようにするために、各APK間で間隔を開けたversion codeのルールを使わなければなりません。

あなたは実際に表示されるバージョンコードと紐づいたバージョン名(android:versionName)もコードに含める必要があります。
ノート:APKのversion codeを増やすとき、Android Marketは前バージョンのユーザーに最新のアプリケーションをアップデートすることを促します。
そのため、不必要なアップデートを避けるために、変化を含まない状態でversion codeを増やすべきではありません。
我々は少なくとも7桁のversion codeを使用することを提案しています。
サポートする機器構成に基づく番号は高い桁で、バージョン名は下位の桁です。
例えばVersionNameが3.1.0の場合で、APIレベル4とAPIレベル11向けのAPKは0400310と1100310のように付番します。
最初の2桁はAPIレベルのために予約し、中間の2桁はスクリーンサイズかGLテクスチャーフォーマットのために、最後の3桁がバージョン名です。
プラットフォーム版とスクリーンサイズに基づく場合の2つの例を示します。
0412310
APIレベル(4+)スクリーンサイズ(small-normal)Appバージョン(3.1.0)
1134310
APIレベル(11+)スクリーンサイズ(large-xlarge)Appバージョン(3.1.0)


APIレベルのために最初の2桁を使用し、
続く2から3桁を最大のスクリーンサイズ(1〜4でそれぞれのサイズを示す またはテクスチャーフォーマット)バージョン名のために最後の3桁を使用する。
バージョンコードの計画はアプリケーションをバージョンアップしながらスケーラブルなパターンを確立するための提案です。
この方法では異なるテクスチャー圧縮フォーマットに対しての対応を解決していません。
アプリケーションがサポートするテクスチャーを示すテーブルを定める必要があるかもしれません。
希望するどんな計画にも従うことが出来ますが、アプリケーションが将来どのようにバージョンコードを増やす必要があるか、そして機器構成がどのようにアップデートされていくかを慎重に考えなければなりません。

1つのAPKを使用する

MultipleAPKを作ることはAndroid Market上にアプリケーションを配布する通常の手続きではありません。
殆どの場合、1つのAPKで大部分のユーザー向けアプリケーションを公開できるはずです。
我々はそれを推奨します。

1つのAPKを使用するのが難しくなっても、MultipleAPKを使用する前に他の方法を慎重に考慮しなければなりません。
全てのデバイスをサポートするAPKを開発することが有利になる2,3の理由があります。

アプリケーションを公開して管理することが簡単です。
どのAPKかについて混同することなく、1つのAPKについてのみ考えることが出来ます。
複数のversion codeについて経過を追う必要がありません。 単にバージョンコードを増やすことが出来ます。

管理すべきソースコードは1つです。
コードを複数のAndroidプロジェクトで共有するライブラリプロジェクトを使用することが出来ますが、各プロジェクトでソースコードを複製したりして、特にデバッグ時に管理するのが困難になりそうです。

デバイス構成全てを含む1つのAPKを作ることによって実行時の構成変化に対応できます。
たとえば、機器がドックに接続されたり、携帯電話が大きなスクリーンに接続された場合、システム構成が変更されることがあります。
1つのAPKで異なるスクリーン構成全てを含めるならば、アプリケーションは代わりのリソースを読み込む事で新しいUIを最適化します。

アプリの復元が異なる構成の装置で働きます。
ユーザーがデータをバックアップし、異なる構成の装置にリストアした場合、その装置に最適化されたリソースで動きます。
例えばタブレットでリストアした場合、タブレットに最適化されたリソースで実行されます。
このリストアプロセスでは各APKにユーザーが許可していない権限がある可能性があるため、MultipleAPKでは動きません。
もし、MultipleAPKを使用した場合、ユーザーは新しい装置のためのAPKを手動でダウンロードしなければいけません。
MultipleAPKを公開すると決める前に、複数の機器構成をサポートする他の方法を以下のセクションで記載します。

複数のGLテクスチャーサポート

1つのAPKで複数のタイプのGLテクスチャーをサポートし、適切な資源をサポートしるようにアプリケーションは装置に問い合せます。
APKのサイズを少なくするために、アプリケーションの初期起動時にテクスチャーフォーマットに対するサポートを問合せてそれに応じたテクスチャーだけをダウンロードすることが出来ます。
最大のパフォーマンスと互換性のために、品質が低くてもETC1テクスチャーを使う必要があります。
しかしETC1は急激な彩度変化(線画やテキストなど)があるイメージに対応できず、アルファも使えないので最適なフォーマットではないかもしれません。
1つのAPKで合理的な場合はETC1と圧縮されていないテクスチャーを使おうとする必要があり、ETC1では不足するときの手段としてPVRTCやATITC、DXTCの使用を検討します。
テクスチャーの組み合わせ例はGLSurfaceView.Rendererを参照してください

public void onSurfaceChanged(GL10 gl, int w, int h) {
String extensions = gl.glGetString(GL10.GL_EXTENSIONS);
Log.d("ExampleActivity", extensions);
}

これはサポートする圧縮フォーマットをリストした文字列を返します。

複数の画面サポート

APKファイルが50MBを上回らない限り、複数の画面サポートは1つのAPKで行う必要があります。
Android1.6より複数の画面サイズと解像度で適切に動きたいという要求に応えて、います。
異なるスクリーンサイズと解像度への要望を最適化するために、代わりのリソース(異なるサイズのビットマップやレイアウトデザイン)を提供しなければなりません。
1つのAPKで複数の画面をサポートする方法の詳細はSupporting Multiple Screensを読んでください。
加えてタブレットのような大きなスクリーンで動くときにFragmentsをActivityのデザインで使用できるようにCompatibility Packageのサポートライブラリを使うことを検討する必要があります。

複数のAPIレベルサポート

できるだけ多くのAndroidプラッごフォームのバージョンをサポートするなら、
必要な最小のバージョンで利用出来るAPIだけを使用する必要があります。
例えばAndroid2.1(API Level7)より新しいAPIを必要としないかもしれません。
それは、Androidで動くデバイスの95%以上が利用出来るアプリケーションを作成することになります。
訳注:残り5%のユーザーとしてのお願い。 まずはAPI Level4で開発することを検討してください。

Compatibility Packageからのサポートライブラリを使用してAndroid1.6のバージョンをサポートしながらAndroid3.0のいくつかのAPIを使用することも出来ます。
サポートライブラリはFragments,Loadersとその他いくつかのAPIを含みます。
タブレットのような大きな装置のユーザーインターフェイスを最適化出来るようにFragmentAPIを使用することは特に貴重です。
あるいは、Androidの新しいバージョンだけで利用出来るいくつかのAPIを使用するならば、reflectionを使うことを検討してください。
reflectionを使用して現在のデバイスが特定のAPIをサポートするかどうか調べることが出来ます。
APIが利用できないならば、アプリケーションはその機能を動かさなくして隠すことが出来ます。
新しいAPIレベルをチェックすることがある場合にだけ新しいAPIを使用するもうひとつの方法
SDK_INTの値を問い合わせ、装置でサポートされるAPIレベルによって異なるコードをたどることが出来ます。
例えば

if (android.os.Build.VERSION.SDK_INT >= 11) {
// Use APIs supported by API level 11 (Android 3.0) and up
} else {
// Do something different to support older versions
}

前:Effective Java 輪講第三回の復習 次:脱Excel方眼 Word超入門

関連キーワード

[Android][Java][モバイル][IT][翻訳]

コメントを投稿する