page.title=アプリケーションの基礎 @jd:body
Android アプリは Java プログラミング言語で記述されています。APKAndroid SDK ツールがコードを—データとリソース ファイルと共に、 —APK (Android パッケージ)にコンパイルします。これは、 {@code .apk} という接尾語の付いたアーカイブ ファイルです。1 つの APK ファイルにはAndroid アプリのすべてのコンテンツが含まれており、Android 端末はアプリをインストールする際にこのファイルを使用します。
端末にインストールすると、各 Android アプリはそれぞれのセキュリティ サンドボックス内で動作します。
このようにして、Android システムは最小権限の原則を実装しています。つまり、デフォルトでは各アプリにはコンポーネントの動作に必要な分だけのアクセス権が与えられます。 これにより、パーミッションの与えられていないシステムの一部にアプリはアクセスできないという非常に安全性の高い環境が作り出されます。
ただし、アプリが他のアプリとデータを共有したり、システムのサービスにアクセスしたりする方法もあります。
以上が、システム内の Android アプリの基本的な仕組みです。続いて、このドキュメントでは次の内容について説明します。
アプリのコンポーネントは、Android アプリに不可欠な構成要素です。各コンポーネントは、システムがアプリにアクセスするためのさまざまなエントリ ポイントになります。すべてのコンポーネントがユーザーの実際のエントリ ポイントになるわけではなく、中にはお互いに依存関係にあるものもありますが、それぞれが独自のエンティティとして存在し、特定の役割を担っています。各コンポーネントはアプリの全体的な動作を定義する固有の構成要素となっています。 —
アプリのコンポーネントには、4 つのタイプがあります。それぞれのタイプは、まったく異なる目的を果たし、コンポーネントの作成や破棄方法を定義するライフサイクルもそれぞれ異なります。
アプリのコンポーネントのタイプは次の 4 つです。
アクティビティは {@link android.app.Activity} のサブクラスとして実装されます。詳細については、デベロッパー ガイドの「Activities」をご覧ください。
サービスは {@link android.app.Service} のサブクラスとして実装されます。詳細については、デベロッパー ガイドの「サービス」をご覧ください。
コンテンツ プロバイダは、アプリで非公開扱いの共有されていないデータを閲覧したり書き込んだりする場合にも役立ちます。 たとえば、Note Pad のサンプル アプリでは、コンテンツ プロバイダを使用してメモを保存します。
コンテンツ プロバイダは {@link android.content.ContentProvider} のサブクラスとして実装され、他のアプリがトランザクションを実行できるようにする API の標準セットを実装する必要があります。 詳細については、デベロッパー ガイドの「Contetns Providers」をご覧ください。
ブロードキャスト レシーバーは、{@link android.content.BroadcastReceiver} のサブクラスとして実装され、各ブロードキャストは {@link android.content.Intent} オブジェクトとして配信されます。 詳細については、{@link android.content.BroadcastReceiver} クラスをご覧ください。
Android ならではのシステムデザインによって、どのアプリケーションからでも別のアプリケーションを開始できます。 たとえば、ユーザーが端末のカメラで写真を撮影できるようにする場合、既にその機能を備えた別のアプリがあることを想定して、写真を撮影するアクティビティを自身で開発する代わりに、アプリがそれを使用できます。 カメラアプリを組み込んだり、コードにリンクしたりする必要もなく、単純に写真を撮影するカメラアプリのアクティビティを開始するだけです。 完了後、写真はアプリに戻り、それを使用することもできます。ユーザー側には、カメラがアプリの一部であるかのように見えます。
システムがコンポーネントを開始すると、そのアプリのプロセスを開始し(まだ実行していない場合)、コンポーネントが必要とするクラスをインスタンス化します。 たとえば、アプリで写真を撮影するカメラアプリのアクティビティを開始すると、そのアクティビティはアプリのプロセスではなく、カメラアプリのプロセスで実行します。そのため、他のシステムのアプリとは異なり、Android アプリのエントリ ポイントは 1 つではありません(たとえば、{@code main()} 関数はありません)。
システムは、他のアプリへのアクセスを制限するファイル許可を使用して各アプリを別々のプロセスで実行するため、アプリから直接他のアプリのコンポーネントはアクティベートできませんが、Android システムはそれが可能です。 そのため、他のアプリのコンポーネントをアクティベートするには、特定のコンポーネントを開始するインテントを指定するメッセージをシステムに配信する必要があります。 その後、システムが代わりにコンポーネントをアクティベートします。
4 つのコンポーネント タイプのなかで、アクティビティ、サービス、ブロードキャスト レシーバーの 3 つは、インテントと呼ばれる非同期メッセージによってアクティベートされます。コンポーネントがアプリに属していても他のものに属していても、インテントにより実行時に個別のコンポーネントがお互いに結び付けられます(他のコンポーネントからのアクションを要求するメッセンジャーのようなものです)。——
インテントは {@link android.content.Intent} オブジェクトを使用して作成されます。このオブジェクトは特定のコンポーネントや特定のタイプのコンポーネントをアクティベートするようにメッセージを定義します。インテントはそれぞれ明示的、暗黙的のいずれかになります。—
アクティビティとサービスでは、インテントが実行するアクション(「閲覧」したり「送信」したりする)を定義し、操作に使うデータ(特に、開始されるコンポーネントが知っておく必要があるデータ)の URI を指定することもできます。 たとえば、インテントはアクティビティに画像を表示したり、ウェブページを開いたりするアクティビティに対して要求を伝達します。 場合によっては、結果を受け取るアクティビティを開始でき、この場合にアクティビティが返す結果も {@link android.content.Intent} になります(たとえば、ユーザーが個人の連絡先を取り出し、それを返してくれるインテントを発行できます。返されたインテントには選択された連絡先を指す URI が含まれています)。 —
ブロードキャスト レシーバーの場合、インテントは単純にブロードキャストするアナウンスを定義します(たとえば、端末のバッテリ残量が少ないことを示すブロードキャストには、「バッテリが少ない」ことを示す既知のアクション文字列が含まれます)。
他のコンポーネント タイプであるコンテンツ プロバイダは、インテントではアクティベートされず、{@link android.content.ContentResolver} からの要求の対象となったときにアクティベートされます。 コンテンツリゾルバが、コンテンツプロバイダを使ってすべてのトランザクションを直接処理することで、プロバイダを使ってトランザクションを実行しているコンポーネントは処理する必要がなくなり、代わりに {@link android.content.ContentResolver} オブジェクトのメソッドを呼び出します。 これによりコンテンツ プロバイダと情報を要求しているコンポーネントとの間に(セキュリティ目的で)抽象的な層ができます。
各コンポーネント タイプのアクティベート用に、個別のメソッドが用意されています。
インテントの使用に関する詳細については、「インテントとインテント フィルタ」のドキュメントをご覧ください。 特定のコンポーネントのアクティベートの詳細については、 アクティビティ、サービス、{@link android.content.BroadcastReceiver}、コンテンツ プロバイダ のドキュメントでも説明しています。
Android システムがコンポーネントを開始する前に、システムはアプリの {@code AndroidManifest.xml} ファイル(「マニフェスト」ファイル)を読み取って、コンポーネントの存在を認識する必要があります。 アプリはこのファイルですべてのコンポーネントを宣言し、このファイルはアプリ プロジェクトのディレクトリのルートに置く必要があります。
マニフェストはアプリのコンポーネントを宣言する他にも、次のようにさまざまな役割があります。
マニフェストの主なタスクは、システムにアプリ コンポーネントに関する情報を与えることです。たとえば、マニフェスト ファイルではアクティビティを次のように宣言できます。
<?xml version="1.0" encoding="utf-8"?> <manifest ... > <application android:icon="@drawable/app_icon.png" ... > <activity android:name="com.example.project.ExampleActivity" android:label="@string/example_label" ... > </activity> ... </application> </manifest>
<application>
要素では、{@code android:icon} 属性でアプリを特定するアイコンのリソースを指します。
<activity>
要素では、{@code android:name} 属性で{@link
android.app.Activity} サブクラスの完全修飾k裏スパイウェア名を指定し、{@code android:label} 属性でアクティビティのユーザーに表示するラベルとして使用する文字列を指定しています。
すべてのアプリ コンポーネントは、次の方法で宣言する必要があります。
<activity>
アクティビティ用の要素
<service>
サービス用の要素
<receiver>
ブロードキャスト レシーバー用の要素
<provider>
コンテンツ プロバイダ用の要素
ソースに含まれていながら、マニフェスト ファイルでは定義されていないアクティビティ、サービス、コンテンツ プロバイダはシステムには見えないため、実行されることはありません。 ただし、ブロードキャスト レシーバーはマニフェストで宣言するか、コードで動的に作成({@link android.content.BroadcastReceiver} オブジェクトとして)して {@link android.content.Context#registerReceiver registerReceiver()} を呼び出すことでシステムに登録できます。
アプリのマニフェスト ファイルの構築方法の詳細については、「The AndroidManifest.xml File」のドキュメントをご覧ください。
コンポーネントをアクティベートするで説明したように、{@link android.content.Intent} を使用してアクティビティ、サービス、ブロードキャスト レシーバーを開始できます。 開始するには、インテントでターゲットのコンポーネントの名前を(コンポーネントのクラス名を使って)明示的に指定する必要があります。 ただし、インテントの本来の能力は、暗黙的インテントの概念にあります。 暗黙的インテントは、単に実行するアクションのタイプを記述し(どのデータ上でアクションを実行するかも任意で記述できます)、それによりシステムがそのアクションを実行できる端末上のコンポーネントを見つけて開始できます。 インテントで記述されたアクションを実行できるコンポーネントが複数ある場合は、使用するコンポーネントを 1 つ選択できます。
システムは、端末の他のアプリのマニフェスト ファイルに提供されたインテント フィルタが受け取った インテントを比較して、 インテントに応答できるコンポーネントを識別します。
アプリのマニフェストでアクティビティを宣言するとき、任意でアクティビティの機能を宣言するインテント フィルタを含めて、他のアプリからのインテントに応答できるようにできます。 {@code <intent-filter>} 要素を、コンポーネントを宣言している要素の子として追加することで、コンポーネントのインテント フィルタを宣言できます。
たとえば、新規メールを作成するアクティビティを持つメールアプリをビルドした場合、次のように「送信」インテント(新規メールを送信するための)に応答するインテント フィルタを宣言できます。
<manifest ... > ... <application ... > <activity android:name="com.example.project.ComposeEmailActivity"> <intent-filter> <action android:name="android.intent.action.SEND" /> <data android:type="*/*" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> </application> </manifest>
次に、別のアプリが {@link android.content.Intent#ACTION_SEND} アクションを持つインテントを作成し、{@link android.app.Activity#startActivity startActivity()} に渡す場合、ユーザーがメールを下書きして送信できるよう、システムがアクティビティを開始する場合があります。
インテント フィルタの作成の詳細については、「インテントとインテント フィルタ」のドキュメントをご覧ください。
Android が搭載された端末は数多くありますが、すべての端末が同じ機能や性能を備えているわけではありません。 アプリに必要な機能を搭載していない端末にアプリをインストールしてしまわないよう、アプリがサポートする端末のタイプについてプロファイルで明確に定義し、マニフェスト ファイルで端末の要件やソフトウェア要件を宣言しておくことが重要です。 これらの宣言のほとんどはただの情報で、システムがそれを読み取ることはありませんが、Google Play などの外部サービスはそれを読み取って、ユーザーが端末からアプリを検索したときにフィルタを提供します。
たとえば、アプリでカメラを使用する必要があり、Android 2.1 で採用された API(API レベル 7)を使用する場合、次のようにマニフェスト ファイルでそれを要件として宣言する必要があります。
<manifest ... > <uses-feature android:name="android.hardware.camera.any" android:required="true" /> <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="19" /> ... </manifest>
カメラのない端末で、Android バージョンが 2.1 以下の場合は、Google Play からアプリをインストールできません。
ただし、アプリでカメラを使用するが、それが必須ではないということを宣言することもできます。 この場合、アプリで {@code required} 属性を {@code "false"} に設定し、端末にカメラがあるかどうかを実行時に確認して、必要に応じてすべてのカメラ機能を無効にする必要があります。
異なる端末でのアプリの互換性を管理する方法については、「Device Compatibility」をご覧ください。
Android アプリは、コードだけで構成されているわけではありません。ソース コードから分離された画像、オーディオ ファイル、その他アプリの外観に関連するあらゆるリソースが必要です。たとえば、アクティビティのアニメーション、メニュー、スタイル、色、レイアウトなどを XML ファイルで定義する必要があります。— アプリのリソースを使用すると、コードを修正することなく別のリソースセットを提供することで、アプリのあらゆる特性を簡単にアップデートできるようになります。これにより、さまざまな端末の設定用(別の言語や画面サイズなど)にアプリを最適化できます。 — —
Android プロジェクトに含めるすべてのリソースに対し、SDK ビルド ツールが一意の整数 ID を定義し、アプリコードや XML で定義された他のリソースからリソースにそれを使って参照できます。 たとえば、アプリに {@code logo.png} という名前の画像ファイルがある場合({@code res/drawable/} ディレクトリ内に保存)、SDK ツールが {@code R.drawable.logo} という名前のリソース ID を生成し、これを使って画像を参照してユーザー インターフェースに挿入できます。
リソースとソース コードを分離して提供する方法の最も重要な側面は、さまざまな端末設定に合わせて別のリソースを提供できるという点です。 たとえば、XML で UI 文字列を定義することで、その文字列を他の言語に翻訳して、それらの文字列を別のファイルに保存しておくことができます。 それを、リソースのディレクトリ名に付けた言語の修飾子(フランス語の文字列値なら {@code res/values-fr/} のように)とユーザーの言語設定に基づいて、Android システムによって UI に適切な言語の文字列が適用されます。
Android では代替リソース用に多様な修飾子をサポートしています。修飾子は、リソースのディレクトリ名に含める短い文字列で、そのリソースを使用する端末構成を定義するものです。 例をもう 1 つ挙げると、端末の画面の向きやサイズによって、アクティビティのレイアウトを複数作成する必要があります。 たとえば、端末が縦方向(縦長)の場合、ボタンの付いたレイアウトを縦に並べ、端末が横方向(横長)の場合はボタンを横並びにする、といった場合です。 画面の方向によってレイアウトを変更するには、2 つの異なるレイアウトを定義して、それぞれのレイアウトのディレクトリ名に適切な修飾子を適用します。 そうすることで、現在の端末の向きによってシステムが自動的に適切なレイアウトを適用できます。
アプリケーションに含めることのできるリソースの種類や、異なる端末設定用の代替リソースの作成方法については、「リソースの提供」をご覧ください。