From d81d0ed9c5becc586f4e23d42762cd21e104079a Mon Sep 17 00:00:00 2001
From: Dirk Dougherty 「Android Development Tools (ADT) plugin for Eclipse」は、Eclipse 統合開発環境に強力な拡張機能を追加します。拡張機能により、Android アプリケーションの作成とデバッグが容易になります。Eclipse を使用している場合、ADT プラグインを組み込むことで、Android アプリケーションを驚くほど効率よく開発できるようになります: ADT を組み込んだ Eclipse 総合開発環境で Android アプリケーションの開発を始めるには、最初に Eclipse 総合開発環境をダウンロードしてから、ADT プラグインをダウンロードしてインストールする必要があります。そのためには、Eclipse 用 ADT プラグインのインストールに記載されている手順どおりに操作します。 バージョン 0.9 より前の ADT を使用してアプリケーションを既に開発中の場合は、必ず最新バージョンにアップグレードしてから続行してください。Eclipse ADT プラグインをアップデートするためのガイドをご覧ください。 注: このガイドでは、ADT プラグインの最新バージョンを使用していることを前提としています。説明の大半は、以前のバージョンにも当てはまりますが、以前のバージョンを使用している場合は、このドキュメントのオンライン版ではなく、SDK パッケージに付属された資料内の同ドキュメントをご覧ください。 ADT プラグインが提供する新規プロジェクト ウィザードを使用すると、簡単に Android プロジェクトを新規作成(または既存のコードから作成)できるようになります。新しいプロジェクトを作成するには: 最新の SDK に導入されている新しい API を使用することがわかっている場合を除き、Android 1.1 などの最も古いバージョンのターゲット (Target Name) を選択してください。 注: プロジェクトのビルド ターゲットはいつでも変更できます。変更するには、[パッケージ エクスプローラー(Package Explorer)] でプロジェクトを右クリックし、[プロパティ(Properties)] を選択し、[Android] を選択して、指定するプロジェクト ターゲットのチェックボックスをオンにします。 ヒント: 新規プロジェクト ウィザードは、ツールバーの [新規(New)] アイコンからも開始できます。 新規プロジェクト ウィザードを完了すると、ADT は新しいプロジェクトに次のフォルダとファイルを作成します: 注意してください。アプリケーションを Android エミュレータで実行する前に、Android 仮想デバイス(AVD)を作成する必要があります。AVD では、エミュレータで使用する Android プラットフォームを指定します。詳しくは Android 仮想デバイス のドキュメントをご覧ください。ただし、すぐにアプリケーションを実行したい場合は、次の簡単な手順に従って AVD を作成してください。 携帯端末の実機でのみアプリケーションを実行する場合は、AVD は必要ありません。この場合のアプリケーションの実行について詳しくは、Developing On a Device をご覧ください。 詳しい説明はこのドキュメントの範囲外なので、AVD を作成する基本的な手順のみをここに示します: 次のように選択可能な Android ターゲットのリストが表示されます: アプリケーションを実行する Android プラットフォームに一致するターゲットを探します。 これで AVD が作成できました。次のセクションでは、エミュレータでアプリケーションを起動する際に、AVD がどのように使用されるかについて説明します。 AVD の作成と管理について詳しくは、Android 仮想デバイス のドキュメントをご覧ください。 注: アプリケーションを実行する前に、アプリケーションのビルド ターゲットを満たすターゲットを指定した AVD を必ず作成してください。ビルド ターゲットの要件を満たす AVD が見つからない場合、それを示すコンソール エラーが表示され、起動は中止されます。 アプリケーションを実行(またはデバッグ)するには、Eclipse のメイン メニューで [実行(Run)] > [実行(Run)](または [実行(Run)] > [デバッグ(Debug)])を選択します。ADT プラグインはそのプロジェクトのデフォルトの起動構成を自動的に作成します。 アプリケーションの実行またはデバッグを選択すると、Eclipse では以下が行われます: デフォルトでは、Android アプリケーションの起動構成ではデバイス ターゲットの選択に「自動ターゲット」モードを使用します。自動ターゲット モードでの配備ターゲットの選択について詳しくは、下記の自動または手動のターゲット モードをご覧ください。 デバッグの場合は、アプリケーションは「デバッガ待ち」モードで開始されます。デバッガの接続後、Eclipse はデバッグ パースペクティブを開きます。 プロジェクトで使用する起動構成を設定または変更するには、構成マネージャを使用します。詳しくは起動構成の作成をご覧ください。 起動構成では、実行するプロジェクト、開始する Activity、使用するエミュレータ オプションなどを指定します。プロジェクトを初めて Android アプリケーションとして実行すると、ADT は自動的に起動構成を作成します。デフォルトの起動構成は、デフォルトのプロジェクト アクティビティを起動し、自動ターゲット モードで端末を選択します(優先 AVD が指定されていない場合)。デフォルト設定がプロジェクトに適さない場合は、起動構成をカスタマイズするか、新規作成することができます。 起動構成を作成または変更するには、使用している Eclipse のバージョンに合わせて、次の手順どおりに操作します: [ターゲット(Target)] タブでは、アプリケーションを実行する AVD の選択を手動(Manual)モードで行うか、自動(Automatic)モードで行うかを考えます(次の自動または手動のターゲット モードのセクションをご覧ください)。 デフォルトでは、起動構成には、自動ターゲット モードで選択された AVD が使用されます。このモードでは、ADT は次の方法により、アプリケーションの AVD を選択します: ただし起動構成で「優先 AVD」が選択されている場合は、アプリケーションは常にその AVD に配備されます。その AVD がまだ実行されていない場合は、新しいエミュレータが起動されます。 起動構成が手動モードの場合は、アプリケーションを実行するたびに、「Device Chooser」が表示されるので、使用する AVD を選択できます。 Android アプリケーションの開発を始めると、Android アプリケーションをシステムがエミュレータや実機にインストールする前に、どの Android アプリケーションにもデジタル署名が必要であることがわかります。署名には、デバッグ キーを使用する方法(エミュレータや開発用端末ですぐにテストする場合)と、非公開キーを使用する方法(アプリケーションを配布する場合)の 2 つがあります。 ADT プラグインでは、アプリケーションをエミュレータや開発用端末にインストールする前に、.apk ファイルがデバッグ キーを使用して署名されるので、開発を早めることができます。つまり、独自の非公開キーを生成する必要がなく、Eclipse からアプリケーションをすぐに実行できます。Keytool に ADT がアクセスできれば、デベロッパーが特に操作する必要はありません。ただし、アプリケーションを公開する場合は、SDK ツールが生成するデバッグ キーではなく、独自の非公開キーを使用してアプリケーションに署名する必要があります。 アプリケーションへの署名をご覧ください。Android でのアプリケーションへの署名と、Android アプリケーション デベロッパーにとっての署名の意味について説明しています。このドキュメントには、ADT のエクスポート ウィザードを使用してアプリケーションをエクスポートし、署名するためのガイドも含まれています。 Eclipse のブレークポイントで中断したとき、任意のコードを実行できます。たとえば「zip」という文字列引数を使用する関数では、パッケージと呼び出しクラスのメソッドに関する情報を取得できます。任意の静的メソッドを呼び出すこともできます。たとえば コードの実行ウィンドウを開き、メイン メニューから [ウィンドウ(Window)] > [ビューの表示(Show View)] > [表示(Display)] を選択すると、簡単なテキスト エディタである [表示(Display)] ウィンドウが開きます。式を入力し、そのテキストをハイライト表示し、'J' アイコンをクリックして(または Ctrl+Shift+D キーを押して)そのコードを実行します。コードは、選択したスレッド(ブレークポイントまたはシングルステップ ポイントで停止している必要があります)のコンテキストで実行されます(手動でスレッドを強制停止した場合は、シングルステップを 1 回実行する必要があります。スレッドが Object.wait() 状態の場合は、上記を実行できません)。 現在、ブレークポイントで中断している場合は、ソース コードの一部をハイライト表示し、Ctrl+Shift+D キーを押して実行することができます。 同じスコープ内のテキストの一部をハイライト表示するには、Alt+Shift+上矢印キーを押して、より広い範囲の閉じたブロック(複数可)を選択するか、下矢印キーを押して選択範囲を小さくすることができます。 Eclipse で [表示(Display)] ウィンドウを使用した入力とその応答のサンプルを次に示します。 デバッガではなくスクラップブック ページを使用しても、任意のコードを実行できます。Eclipse ドキュメントで「スクラップブック」を検索してください。 ADT プラグインを使用するデバッグをおすすめしますが、手動で DDMS を実行し、ポート 8700 でデバッグするように Eclipse を設定することができます(注: 最初に必ず DDMS を起動してください)。 Android アプリケーションの開発では、ADT プラグイン搭載の Eclipse を使用する開発方法が推奨されています。ADT プラグインは、編集、ビルド、デバッグ、.apk パッケージング、署名の機能を統合開発環境に直接統合して提供します。 しかし Eclipse の代わりに IntelliJ のような別の総合開発環境や Emacs のような基本的なエディタを使用した開発も可能です。SDK には Android プロジェクトのセットアップ、ビルド、デバッグ、および配布用パッケージ作成に必要なすべてのツールが含まれています。このドキュメントでは、こうしたツールの使用方法について説明します。 Eclipse 以外の統合開発環境やエディタで開発する際には、次の Android SDK ツールについて知っておく必要があります: 上記のツールに加えて、SDK に含まれている次のオープンソースとおよびサードパーティ製のツールを使用します: 下記のトピックでは、必要な箇所でそれぞれの各ツールを説明しています。さらに高度な操作については、ツールのそれぞれのドキュメントをご覧ください。 Android プロジェクトを作成するには、 新しいプロジェクトを開始する場合、 新しい Android プロジェクトを作成するには、コマンドラインを開き、SDK の 次に例を示します: このツールは次のファイルとディレクトリを生成します: プロジェクトを作成すると、開発を始める準備ができます。開発のために、プロジェクト フォルダをどこにでも移動できますが、アプリケーションをエミュレータに送信するために(方法については後述します)、SDK の 注: SDK ディレクトリは移動させないでください。移動するとビルド スクリプトが機能しなくなります(ビルド スクリプトをもう一度機能させるには、手動でスクリプトを更新して、SDK の新しいロケーションを反映させる必要があります)。 Android SDK の古いバージョンからプロジェクトをアップグレードする場合や、既存のコードから新しいプロジェクトを作成する場合は、 既存の Android プロジェクトを更新するには、コマンドラインを開き、SDK の 次に例を示します: Android アプリケーションの開発を始めると、Android アプリケーションをエミュレータや端末上のシステムにインストールする前に、どの Android アプリケーションにもデジタル署名が必要であることがわかります。解決策としては「デバッグ キー」を使用する方法(エミュレータや開発用端末上ですぐにテストする場合)と、非公開キーを使用する方法(アプリケーションを配布する場合)の 2 つがあります。 Android のビルド ツールを使用すると、ビルド時にデバッグキーを使用して .apk ファイルに自動的に署名できるので、スムーズな開発が可能です。つまり、独自の非公開キーを生成しなくても、アプリケーションをコンパイルして、エミュレータにインストールすることができます。ただし、アプリケーションを公開する場合は、SDK ツールが生成したデバッグ キーではなく、独自の非公開キーを使用してアプリケーションに署名する必要があります。 アプリケーションへの署名をご覧ください。Android でのアプリケーションへの署名と、Android アプリケーション デベロッパーにとっての署名の意味について説明しています。 アプリケーションのビルドには、アプリケーションをテスト/デバッグするための「デバッグ モード」と、リリース用の最終パッケージをビルドするための「リリース モード」の 2 つがあります。前のセクションで説明したように、アプリケーションをエミュレータや端末にインストールする前に、アプリケーションに署名する必要があります。 デバッグ モードとリリース モードのどちらでビルドしているかに関係なく、プロジェクトをコンパイルし、ビルドするには Ant ツールが必要です。これにより、エミュレータや端末にインストールする .apk ファイルが作成されます。デバッグ モードでビルドすると、.apk ファイルは SDK ツールによりデバッグ キーを使用して自動的に署名されるので、インストールの準備がすぐに整います(ただし、エミュレータまたは接続された開発用端末上にのみインストールできます)。リリース モードでビルドされた .apk ファイルは署名されないので、Keytool と Jarsigner を使って、独自の非公開キーで手動で署名する必要があります。 アプリケーションへの署名の内容をよく理解する必要があります。また、アプリケーションをリリースしてエンドユーザーと共有することを計画している場合は非常に重要です。「アプリケーションへの署名」では、非公開キーを生成し、それを使用して .apk ファイルに署名する手順について説明しています。ただし、開発を始めたばかりであれば、デバッグ モードでビルドすることにより、エミュレータまたは独自の開発用端末でアプリケーションをすぐに実行できます。 Ant をお持ちでない場合は、Apache Ant ホームページから入手してください。Ant をインストールして、必ず実行可能パスに置きます。Ant を実行する前に、「JAVA_HOME」環境変数を宣言して JDK のインストールパスを指定する必要があります。 注: Windows 上に JDK をインストールすると、デフォルトでは「Program Files」ディレクトリにインストールされます。このパス名にはスペースが含まれるために、 アプリケーションのテストとデバッグをすぐに行いたい場合は、デバッグ モードでアプリケーションをビルドし、すぐにエミュレータにインストールすることができます。デバッグ モードでは、ビルド ツールはデバッグ キーを使用してアプリケーションに自動的に署名します。ただしアプリケーションはリリース モードでテストすることも可能であり、リリース モードでのテストは推奨されています。デバッグ モードは、手動でアプリケーションに署名しなくても、アプリケーションを実行できるようにします。 デバッグ モードでビルドするには: Android アプリケーションの .apk ファイルがプロジェクトの ソース ファイルまたはリソースを変更するたびに、アプリケーションの最新バージョンをパッケージングするために、Ant を再度実行する必要があります。 アプリケーションをエミュレータにインストールして実行する方法については、下記のアプリケーションの実行セクションをご覧ください。 アプリケーションをエンドユーザーにリリースして配布する準備ができたら、アプリケーションをリリース モードでビルドする必要があります。リリース モードでビルドした後、最終的な .apk ファイルを使用して追加のテストとデバッグをすることをおすすめします。 リリース モードでビルドするには: これにより Android アプリケーションの .apk ファイルがプロジェクトの 注: .apk ファイルはこの時点では署名されていません。つまり非公開キーで署名するまで、エミュレータや端末にインストールすることはできません。 リリース モードではアプリケーションを署名せずにビルドを行います。このため、アプリケーションをエンドユーザーに配布するためには、次に非公開キーを使用して署名を行う必要があります。この手順を行う方法については、Signing Your Applicationをご覧ください。 非公開キーを使用してアプリケーションに署名すると、アプリケーションをエミュレータや端末にインストールできるようになります。これについては次のアプリケーションの実行のセクションで説明します。次の方法でウェブ サーバーから端末にインストールすることもできます。署名した APK をウェブサイトにアップロードし、Android ウェブブラウザでその .apk の URL を読み込んでアプリケーションをダウンロードし、インストールを開始します(端末上では、[設定] > [アプリケーション] を選択し、[提供元不明のアプリ] をオンにする必要があります)。 端末のハードウェア以外でアプリケーションを実行する場合は、アプリケーションのインストール先となるエミュレータを起動する必要があります。Android エミュレータのインスタンスは、特有の端末構成に合わせて設定された、特定の Android プラットフォームを実行しています。このプラットフォームと構成は、Android 仮想デバイス(AVD)で定義されます。そのためエミュレータを起動する前に、AVD を定義しなくてはいけません。 端末ハードウェアでアプリケーションを実行する場合は、代わりに、端末のでの開発 をご覧ください。 次のように選択可能な Android ターゲットのリストが表示されます: アプリケーションを実行する Android プラットフォームに一致するターゲットを探します。 SDK の エミュレータのインスタンスが起動し、AVD で定義されたターゲットと構成が実行されます。 SDK の 複数のエミュレータが実行中の場合、 エミュレータで、使用可能なアプリケーションのリストを開き、実行するアプリケーションを探して開きます。 実行するアプリケーションがエミュレータ上にない場合、同じ AVD を指定してエミュレータを再起動してください。Activity を初めてインストールすると、アプリケーション ランチャに表示されず、他のアプリケーションからアクセスできないことがあります。パッケージ マネージャは通常、エミュレータの起動時にしかマニフェストを完全には調べないためです。 ヒント: 実行中のエミュレータが 1 つしかない場合、1 つの簡単なステップで、アプリケーションをビルドし、エミュレータにインストールすることができます。プロジェクトのルート ディレクトリに移動し、Ant を使用してインストール モードでプロジェクトをコンパイルします( 上記で使用したツールについて詳しくは、次のドキュメントをご覧ください: このセクションでは、画面上でのデバッグ情報(CPU の使用率など)の表示方法や、総合開発環境に接続してエミュレータ上で実行するアプリケーションをデバッグする方法について説明します。 Eclipse プラグインを使用すると、デバッガへの接続は自動化されます。しかし他の総合開発環境でも、デバッグ ポートをリッスンしてデバッグ情報を受信するように設定することができます: このドキュメントでは、Android アプリケーションを携帯端末ユーザーに公開する前に署名する方法について説明します。 Android システムでは、インストールするすべてのアプリケーションに対してデジタル署名されて証明書を必要とします。この証明書の秘密鍵は、アプリケーションのデベロッパーが所持するものです。Android システムは証明書をアプリケーションの作成者の識別手段、およびアプリケーション間の信頼関係の確立手段として使用します。証明書は、ユーザーがどのアプリケーションをインストールできるかを制御するものではありません。証明書は認証機関によって署名される必要はありません。通常の Android アプリケーションは自己署名証明書を使用して正常に機能します。 Android アプリケーションの署名について、次の点を理解することが重要です: Android システムは、適切に署名されていないアプリケーションをインストールせず、実行もしません。この規則は、実際のデバイスでもエミュレータでも、Android システムが実行されるすべての状況で適用されます。このため、エミュレータまたはデバイス上で実行またはデバッグする前に、アプリケーションの署名を設定する必要があります。 Android SDK ツールは、デバッグ時のアプリケーション署名を支援します。「ADT Plugin for Eclipse」と「Ant ビルド ツール」では両方とも、デバッグ モードとリリース モードの 2 種類の署名モードを利用できます。
+
+ アプリケーションの署名は、開発アプローチに一部影響します。特に、複数のアプリケーションをリリースする予定の場合、高い影響を与えます。 一般に、すべてのデベロッパーに推奨される戦略は、アプリケーションの予期される使用期間を通じて同じ証明書ですべてのアプリケーションに署名することです。このようにするには、複数の理由があります: 署名戦略を決定する際のもう 1 つの重要な検討事項として、アプリケーションの署名に使用するキーの有効期間の設定方法があります。 アプリケーションの設計時にこれらの点を考慮し、アプリケーションの署名に適切な証明書を使用してください。 キーストアとデバッグ キーの生成をサポートするため、SDK ビルド ツールで Keytool を使用できることを初めに確認してください。たいていの場合、「JAVA_HOME」環境変数を設定して適切な JDK を参照させることで、SDK ビルド ツールで Keytool を認識できます。または、JDK バージョンの Keytool を PATH 変数に追加しても認識できます。 Linux バージョンに付属されている GNU Java コンパイラで開発している場合は、gcj バージョンではなく、JDK バージョンの Keytool を使用していることを確認してください。Keytool が既に PATH に指定されている場合は、 アプリケーションを公開する場合は、Jarsigner ツールをコンピュータで使用できるようにする必要があります。Jarsigner と Keytool の両方が JDK によって提供されます。 Android ビルド ツールにはデバッグ署名モードがあり、アプリケーションの開発とデバッグがスムーズに行えます。また、.apk をエミュレータまたはデバイスにインストールする際の、署名に対する Android システム要件を満たします。デバッグモードでは、SDK ツールは Keytool を呼び出してデバッグ キーストアとキーを作成します。 SDK ツールは事前に指定された名前とパスワードを使用してデバッグ キーストア/キーを作成します。このドキュメントの内容
+
+
+
+
+
+
+Android プロジェクトの作成
+
+
+
+
+
+
+
+
+ minSdkVersion
属性が Android マニフェスト ファイルの <uses-sdk> に自動的に設定されます。使用する適切な API レベルがわからない場合は、ビルド ターゲット(Build Target)にリストされている API レベル(API Level)をコピーします。
+
+
+
+src/
<Android Version>/
(例: Android 1.1/
)android.jar
ファイルが含まれます。これは、新規プロジェクト ウィザードで選択したビルド ターゲットによって決まります。gen/
R.java
ファイル、AIDL ファイルから作成されたインターフェースなど)がこのフォルダに含まれます。assets/
res/
AndroidManifest.xml
default.properties
アプリケーションの実行
+
+AVD の作成
+
+
+
+
+tools/
ディレクトリに移動します。android list targets
+
+id:1
+ Name: Android 1.1
+ Type: platform
+ API level: 2
+ Skins: HVGA (default), HVGA-L, HVGA-P, QVGA-L, QVGA-P
+id:2
+ Name: Android 1.5
+ Type: platform
+ API level: 3
+ Skins: HVGA (default), HVGA-L, HVGA-P, QVGA-L, QVGA-P
+
+ id
の整数を書き留めておき、次のステップで使用します。android create avd --name <your_avd_name> --target <targetID>
+ アプリケーションの実行
+
+
+
+
+起動構成の作成
+
+
+
+
+
+
+
+
+
+
+
+ 自動または手動のターゲット モード
+
+
+
+
+アプリケーションへの署名
+
+Eclipse のヒント
+
+Eclipse での任意の Java コードの実行
+
+android.os.Debug.startMethodTracing()
と入力すると、dmTrace が起動されます。
+
+
+
+ 入力
+ 応答
+
+
+
+ zip
+ (java.lang.String)
+ /work/device/out/linux-x86-debug/android/app/android_sdk.zip
+
+
+ zip.endsWith(".zip")
+ (boolean) true
+
+
+ zip.endsWith(".jar")
+ (boolean) false
DDMS の手動による実行
+
+このドキュメントの内容
+
+
+
+
+
+ 関連項目
+
+主要なツール
+
+
+
+
+
+
+
+Android プロジェクトの作成
+
+android
ツールを使用する必要があります。新しいプロジェクトを android
で作成すると、デフォルトのアプリケーション ファイル、スタブ ファイル、構成ファイル、ビルド ファイルを含むプロジェクト ディレクトリが生成されます。新しいプロジェクトの作成
+
+android create project
コマンドを使用すると、必要なファイルとフォルダがすべて生成されます。tools/
ディレクトリに移動して、次を実行します:
+android create project \
+--target <targetID> \
+--path /path/to/your/project \
+--activity <your_activity_name> \
+--package <your_package_namespace>
+
+
+
+
+
+target
は、アプリケーションの「ビルド ターゲット」です。これは、プロジェクトをビルドする Android プラットフォーム ライブラリ(Google API のようなアドオンも含まれます)に対応します。使用可能なターゲットとそれに対応する ID の一覧を表示するには、android list targets
を実行します。path
は、プロジェクト ディレクトリのロケーションです。このディレクトリが存在しない場合は、自動的に作成されます。activity
は使用する {@link android.app.Activity} クラスの名前です。このクラス ファイルは <path_to_your_project>/src/<your_package_namespace_path>/
内に作成されます。package
はプロジェクトのパッケージ名前空間であり、Java プログラミング言語でのパッケージと同じルールに従います。
+android create project \
+--target 1 \
+--path ./myProject \
+--activity MyActivity \
+--package com.example.myproject
+
+
+
+
+
+AndroidManifest.xml
- アプリケーションのマニフェスト ファイル。指定したプロジェクトの Activity クラスと同期されます。build.xml
- Ant 用のビルド ファイルです。default.properties
- ビルド システム用のプロパティです。このファイルを変更しないでください。build.properties
- ビルド システム用のカスタマイズ可能なプロパティです。このファイルを編集して、Ant が使用するデフォルトのビルド設定をオーバーライドできます。src/your/package/namespace/ActivityName.java
- プロジェクトの作成時に指定した Activity クラスです。bin/
- ビルド スクリプト用の出力ディレクトリです。gen/
- Ant
が生成するファイル(R.java
など)が含まれます。 libs/
- プライベート ライブラリが含まれます。res/
- プロジェクト リソースが含まれます。src/
- ソース コードが含まれます。tests/
- テスト用に、上記のすべての複製が含まれます。tools/
ディレクトリにある Android Debug Bridge(adb)を使用する必要があります。そのためにプロジェクト ソリューションと tools/
フォルダ間でアクセスする必要があります。プロジェクトの更新
+
+android update project
コマンドを使って新しい開発環境に合わせてプロジェクトを更新します。このコマンドを使って(--target
オプションにより)、既存のプロジェクトのビルド ターゲットを修正することもできます。android
ツールは、指定された Android プロジェクトの必要に応じて、欠落している、または更新を必要としているファイルやフォルダの生成を行います。生成物は前セクションに記述されたリストどおりです。tools/
ディレクトリに移動します。ここで次を実行します:
+android update project --target <targetID> --path path/to/your/project/
+
+
+
+
+
+target
は、アプリケーションの「ビルド ターゲット」です。これは、プロジェクトをビルドする Android プラットフォーム ライブラリ(Google API のようなアドオンも含まれます)に対応します。使用可能なターゲットとそれに対応する ID の一覧を表示するには、android list targets
を実行します。path
は、プロジェクト ディレクトリのロケーションです。
+android update project --target 2 --path ./myProject
+
+
+
+アプリケーションへの署名の準備
+
+アプリケーションのビルド
+
+ant
は実行されません。この問題は、JAVA_HOME 変数を次のように指定することで解決できます: set JAVA_HOME=c:\Prora~1\Java\
ただし最も簡単な解決策は、JDK をスペースを含まないディレクトリ(例: c:\java\jdk1.6.0_02
)にインストールすることです。デバッグ モードでのビルド
+
+
+
+
+ant debug
+ bin/
ディレクトリに、<your_DefaultActivity_name>-debug.apk
という名前で作成されます。このファイルはデバッグ キーで署名済みです。リリース モードでのビルド
+
+
+
+
+ant release
+ bin/
ディレクトリに、<your_DefaultActivity_name>.apk
という名前で作成されます。アプリケーションの実行
+
+
+
+
+
+
+
tools/
ディレクトリに移動します。android list targets
+
+id:1
+ Name: Android 1.1
+ Type: platform
+ API level: 2
+ Skins: HVGA (default), HVGA-L, HVGA-P, QVGA-L, QVGA-P
+id:2
+ Name: Android 1.5
+ Type: platform
+ API level: 3
+ Skins: HVGA (default), HVGA-L, HVGA-P, QVGA-L, QVGA-P
+
+ id
の番号を書き留めておき、次のステップで使用します。android create avd --name <your_avd_name> --target <targetID>
+ tools/
ディレクトリから、上記で作成した既存の AVD を使用してエミュレータを起動します:
+ emulator -avd <your_avd_name>
+ tools/
ディレクトリから .apk をエミュレータにインストールします:
+ adb install /path/to/your/application.apk
+ -s
オプションでシリアル番号を指定して、アプリケーションをインストールするエミュレーションを指定する必要があります。次に例を示します:adb -s emulator-5554 install /my/project/path/myapp.apk
+ ant install
)。これにより、アプリケーションがビルドされ、デバッグ キーにより署名され、現在実行中のエミュレータにインストールされます。現在実行中のエミュレータが複数あると、install
コマンドは失敗します。複数のエミュレータからの選択を行うことはできません。
+
+
+
+アプリケーションへのデバッガの接続
+
+
+
diff --git a/docs/html/intl/ja/guide/publishing/app-signing.jd b/docs/html/intl/ja/guide/publishing/app-signing.jd
new file mode 100644
index 0000000..23d8cf7
--- /dev/null
+++ b/docs/html/intl/ja/guide/publishing/app-signing.jd
@@ -0,0 +1,336 @@
+page.title=アプリケーションへの署名
+@jd:body
+
+署名の概略
+
+
+
+
+このドキュメントの内容
+
+
+
+
+関連項目
+
+
+
+概要
+
+
+
+
+
+
+
+
+
+署名戦略
+
+
+
+
+
+
+
+署名の基本設定
+
+/usr/bin/keytool
の symlink を指していることがあります。この場合は、symlink ターゲットが JDK の Keytool を指していることを確認してください。デバッグ モードでの署名
+
+
+
必要に応じて、デバッグ キーストア/キーの場所および名前を変更できます。また、自分で作成したデバッグ キーストア/キーを指定することもできます。Eclipse/ADT で、[[]ウィンドウ(Windows)] > [[]設定(Prefs)] > [[]Android] > [[]ビルド(Build)] を選択します。ただし、自分で作成したデバッグ キーストア/キーは、デフォルトのデバッグ キー(上述)と同じキーストア/キー名とパスワードを使用する必要があります。
+ +注: デバッグ証明書で署名した場合は、アプリケーションを公開できません。
+ +Eclipse/ADT で開発し、Keytool を上記のように設定してある場合は、デバッグモードにおける署名はデフォルトで有効になっています。アプリケーションを実行またはデバッグするときに、ADT は .apk にデバッグ証明書で署名し、エミュレータにインストールします。ADT が Keytool にアクセスできる場合は、ユーザーは特に操作する必要はありません。
+ +Ant を使用して .apk ファイルを構築する場合、デバッグ署名モードは debug
オプションを使用することで有効になります(android
ツールで生成された build.xml
ファイルを使用していることが前提となります)。ant debug
を実行してアプリケーションをコンパイルする際、ビルド スクリプトはキーストア/キーを生成し、.apk に署名します。ユーザーは操作する必要はありません。詳細は、その他の統合開発環境での開発: デバッグモードにおけるビルド をお読みください。
デバッグ モード(Eclipse/ADT と Ant ビルドのデフォルト)でのアプリケーション署名に使用した自己署名証明書には、作成日から 365 日の有効期限が設定されます。
+ +証明書の期限が切れると、ビルド エラーが発生します。Ant ビルドでは、エラーは次のようになります:
+ +debug: +[echo] Packaging bin/samples-debug.apk, and signing it with a debug key... +[exec] Debug Certificate expired on 8/4/08 3:43 PM+ +
Eclipse/ADT では、Android コンソールに同様のエラーが表示されます。
+ +この問題を解決するには、debug.keystore
ファイルを削除します。AVD のデフォルトの格納場所は、OS X と Linux の場合は ~/.android/avd
、Windows XP の場合は C:\Documents and Settings\
、Windows Vista の場合は C:\Users\
です。
次にビルドを行うと、ビルド ツールは新しいキーストアとデバッグ キーを再度生成します。
+ +開発コンピュータがグレゴリオ暦以外のロケールを使用している場合、ビルド ツールが誤って期限切れのデバッグ証明書を生成することがあります。このため、アプリケーションをコンパイルしようとするとエラーが発生します。解決策については、トラブルシューティング トピックの ビルド ツールが期限切れのデバッグ証明書を生成するため、アプリケーションがコンパイルできない をご覧ください。
+ + +アプリケーションを他のユーザーに公開する準備ができたら、次のことを行う必要があります:
+以下のセクションでは、これらの手順を実行する方法について説明します。
+ +ADT プラグイン搭載の Eclipse を使用している場合、これらの手順を実行する代わりに Export Wizard を使用して .apk をコンパイルして秘密鍵で署名できます。Export Wizard では、処理過程で新しいキーストアと秘密鍵の生成も可能です。Eclipse ADT によるコンパイルと署名を参考にコンパイルを行ってください。
+ + +アプリケーションのリリースを準備するには、リリース モードでコンパイルする必要があります。リリース モードでは、Android ビルド ツールはアプリケーションを通常どおりにコンパイルしますが、デバッグ キーで署名しません。
+ +注: 署名されていないアプリケーション、またはデバッグ キーで署名されたアプリケーションはリリースできません。
+ +署名されていない .apk ファイルを Eclipse からエクスポートするには、パッケージ エクスプローラー(Package Explorer)でプロジェクトを右クリックして、[[]Android ツール(Android Tools)] > [[]署名されていないアプリケーション パッケージのエクスポート(Export Unsigned Application Package)] を選択します。次に、署名されていない .apk ファイルの場所を指定します(または、AndroidManifest.xml
ファイルを Eclipse で開き、[[]概要(Overview)] タブを開いて [[]署名されていない .apk のエクスポート(Export an unsigned .apk)] をクリックします)。
Export Wizard では、コンパイルと署名の手順を一緒に処理できます。Eclipse ADT によるコンパイルと署名をご覧ください。
+ +Ant を使用している場合は、必要な作業は Ant コマンドでビルド ターゲットとして「release」を指定するだけです。たとえば、Ant を build.xml ファイルがあるディレクトリから実行している場合、コマンドは次のようになります:
+ +$ ant release+ +
ビルド スクリプトは、アプリケーション .apk を署名せずにコンパイルします。
+ + +アプリケーションの署名を準備するには、まず署名に使用する適切な秘密鍵があることを確認することが必要です。適切な秘密鍵とは、次の条件を満たすものです:
+ +アプリケーションを Android マーケットに公開する予定の場合、2033 年 10 月 22 日までの有効期間が必要です。有効期間がこの日付以前に期限切れになるキーで署名されたアプリケーションは、アップロードできません。 +
自己署名されたキーを使用できます。適切なキーがない場合、Keytool を使用して生成する必要があります。基本設定で説明した手順に従って、Keytool を使用できるようにしてください。
+ +Keytool で自己署名キーを生成するには、keytool
コマンドを使用して以下に示すオプション(および、必要に応じてその他のオプション)を渡します。
注: Keytool を実行する前に、秘密鍵のセキュリティ設定を読んで、キーのセキュリティを確保する方法と、自分とユーザーにとってセキュリティ確保が重要な理由を理解してください。特に、自分のキーを生成する場合、キーストアとキーの両方に強力なパスワードを選択する必要があります。
+ +Keytool のオプション | +説明 | +
---|---|
-genkey | キー ペアを生成します(公開キーと秘密鍵)。 | +
-v | 詳しいメッセージを出力する。 | +
-keystore <keystore-name>.keystore | 秘密鍵を含むキーストアの名前。 | +
-storepass <password> | キーストアのパスワード。 セキュリティ上の注意として、安全なコンピュータで作業している場合を除き、このオプションをコマンド ラインに指定しないでください。指定しなかった場合、Keytool からパスワードの入力が求められます。このため、パスワードはシェルの履歴に記録されません。 |
+
-alias <alias_name> | キーのエイリアス。 | +
-keyalg <alg> | キーの生成時に使用する暗号化アルゴリズム。DSA と RSA の 2 つをサポートしています。 | +
-dname <name> | キーの作成者を識別する、識別名。値は、自己署名証明書の発行者およびサブジェクト フィールドとして使用されます。 このオプションはコマンド ラインで指定する必要はありません。指定しなかった場合、Jarsigner からそれぞれの識別名フィールド(CN、OU など)の入力が求められます。 |
+
-validity <valdays> | キーの有効期間(日数)。 注: 10000 以上の値を推奨します。 |
+
-keypass <password> | キーのパスワード。 +セキュリティ上の注意として、安全なコンピュータで作業している場合を除き、このオプションをコマンド ラインに指定しないでください。指定しなかった場合、Keytool からパスワードの入力が求められます。このため、パスワードはシェルの履歴に記録されません。 |
+
秘密鍵を生成する Keytool コマンドの例を示します。
+ +$ keytool -genkey -v -keystore my-release-key.keystore +-alias alias_name -keyalg RSA -validity 10000+ +
上記のコマンド例を実行すると、Keytool からキーストアとキーのパスワードと、キーの識別名フィールドの指定が求められます。キーストアが my-release-key.keystore
というファイルとして生成されます。キーストアとキーは、入力したパスワードで保護されます。キーストアには 1 つのキーが含まれ、10000 日間有効です。エイリアスは、後で使用する名前で、アプリケーションに署名するときにこのキーストアを参照する名前です。
Keytool の詳細は http://java.sun.com/j2se/1.5.0/docs/tooldocs/#security のドキュメント(英語のみ)をご覧ください。
+ + +リリースする .apk に実際に署名する準備ができたら、Jarsigner ツールを使用して署名できます。基本設定で説明したように、Jarsigner をコンピュータで使用できることを確認してください。また、秘密鍵を含むキーストアがあることも確認してください。
+ +アプリケーションに署名するには、Jarsigner を実行して、アプリケーションの .apk と、.apk の署名に使用する秘密鍵を含むキーストアの両方を参照します。以下の表では、使用できるオプションを示します。
+ +
Jarsigner のオプション | +説明 | +
---|---|
-keystore <keystore-name>.keystore | 秘密鍵を含むキーストアの名前。 | +
-verbose | 詳しいメッセージを出力する。 | +
-storepass <password> | キーストアのパスワード。 セキュリティ上の注意として、安全なコンピュータで作業している場合を除き、このオプションをコマンド ラインに指定しないでください。指定しなかった場合、Jarsigner からパスワードの入力が求められます。このため、パスワードはシェルの履歴に記録されません。 |
+
-keypass <password> | 秘密鍵のパスワード。 セキュリティ上の注意として、安全なコンピュータで作業している場合を除き、このオプションをコマンド ラインに指定しないでください。指定しなかった場合、Jarsigner からパスワードの入力が求められます。このため、パスワードはシェルの履歴に記録されません。 |
+
Jarsigner を使用して my_application.apk
というアプリケーション パッケージに署名する例を、上記で作成したキーストアを使用して示します。
+
$ jarsigner -verbose -keystore my-release-key.keystore +my_application.apk alias_name+ +
上記のコマンドを実行すると、Jarsigner からキーストアとキーのパスワードの入力が求められます。.apk がその場で変更され、.apk は署名されます。.apk に別のキーで複数回署名できます。
+ +.apk が署名されたことを確認するには、次のようなコマンドを使用できます:
+ +$ jarsigner -verify my_signed.apk+ +
.apk が適切に署名されると、Jarsigner から「jar verified」と出力されます。詳細情報が必要な場合は、次のコマンドを使用できます。
+ +$ jarsigner -verify -verbose my_application.apk+ +
または、次のコマンドを使用します。
+ +$ jarsigner -verify -verbose -certs my_application.apk+ +
上記の -certs
オプションが付加されたコマンドでは、「CN=」行が出力され、キーの作成者が示されます。
注: 「CN=Android Debug」と出力される場合、.apk が Android SDK によって生成されたデバッグ キーで署名されたことを示しています。アプリケーションをリリースする予定の場合は、デバッグ キーではなく秘密鍵で署名する必要があります。
+ +Jarsigner の詳細は http://java.sun.com/j2se/1.5.0/docs/tooldocs/#security のドキュメント(英語のみ)をご覧ください。
+ + +ADT 搭載 Eclipse を使用している場合、Export Wizard を使用して署名済み .apk をエクスポートできます(必要に応じて、新しいキーストアを作成することもできます)。Export Wizard は、Keytool と Jarsigner のすべての処理を、コマンド ラインを使用せず、グラフィカル ユーザー インターフェースで署名を実行できます。Export Wizard は Keytool と Jarsigner の両方を使用するため、上記の署名の基本設定の条件を満たすコンピュータで使用できます。
+ +署名された .apk を作成するには、パッケージ エクスプローラー(Package Explorer)でプロジェクトを右クリックして、[[]Android ツール(Android Tools)] > [[]署名済みアプリケーション パッケージのエクスポート(Export Signed Application Package)] を選択します(または、AndroidManifest.xml
ファイルを Eclipse で開き、[[]概要(Overview)] タブを開いて [[]Export Wizard を使用する(Use the Export Wizard)] をクリックします)。表示されたウィンドウには、アプリケーションのエクスポート中に見つかったエラーが表示されます。エラーが見つからなかった場合は Export Wizard で処理を続行します。.apk に署名する秘密鍵の選択や、新しいキーストアと秘密鍵の作成など、アプリケーション署名のプロセスを手順を追って実行できます。
Export Wizard が完了すると、配布可能な署名済み .apk が作成されています。
+ + +秘密鍵のセキュリティ設定は、作成者とユーザーの両者にとって重要です。他人にキーを使用させたり、第三者が見つけて使用できるような安全ではない場所にキーストアとキーを放置したりすると、作成者とユーザー間の信頼が損なわれます。
+ +他者が許可を得ずにキーを取得した場合、その人物はアプリケーションに署名して配布し、本物のアプリケーションを故意に置き換えたり破損させたりすることができます。このような人物は、身元を詐称してアプリケーションに署名して配布し、その他のアプリケーションまたはシステム自体を攻撃したり、ユーザー データを破損させたり盗み出したりすることもあります。
+ +キーの有効期限が切れるまで、秘密鍵のセキュリティを常に適切に維持できるかは、デベロッパーとしての評価を左右します。キーを安全に保つためのヒントをいくつか紹介します。
+ +-storepass
および -keypass
オプションを指定しないようにします。指定すると、パスワードがシェル履歴に記録され、コンピュータのすべてのユーザーがアクセスできるようになります。-storepass
と -keypass
オプションを指定しないようにします。 一般的には、キーの生成、使用、保管に関して常識的な注意を払っていれば、セキュリティを確保することができます。
\ No newline at end of file diff --git a/docs/html/intl/ja/guide/publishing/preparing.jd b/docs/html/intl/ja/guide/publishing/preparing.jd new file mode 100644 index 0000000..f1e7b45 --- /dev/null +++ b/docs/html/intl/ja/guide/publishing/preparing.jd @@ -0,0 +1,154 @@ +page.title=公開の準備 +@jd:body + + + +アプリケーションの公開とは、アプリケーションをテストして適切にパッケージし、Android 搭載の携帯端末のユーザーが利用できる状態にすることです。
+ +アプリケーションを公開して Android 搭載デバイスにインストールするには、いくつかの作業を行ってアプリケーションの準備を整える必要があります。このドキュメントでは、アプリケーションのリリースを成功させるための準備における、重要なチェックポイントを説明しています。 +
+ +アプリケーションを Android マーケットに公開する場合は、アプリケーションの具体的な準備要件について Android マーケットでの公開 もご覧ください。
+ +アプリケーションを公開する方法の一般的な情報については、Publishing Your Applications のドキュメントをご覧ください。
+ +アプリケーションのリリースを準備する前の作業:
+ +アプリケーションの最終コンパイルを実行する前の作業:
+ +アプリケーションのコンパイル
+アプリケーションをコンパイルした後の作業:
+アプリケーションをできる限り広範に徹底的にテストすることが重要です。この作業を支援するため、Android では多数のテスト用クラスとツールを用意しています。{@link android.app.Instrumentation Instrumentation} を使用して JUnit およびその他のテスト ケースを実行できます。また、UI/Application Exerciser Monkey などのテスティング ツールを使用できます。
+ +-dpi
、-device
、-scale
、-netspeed
、-netdelay
、-cpu-delay
などのエミュレータ オプションを使用して、エミュレータの画面、ネットワーク パフォーマンス、その他の属性をモデル化して可能な限り対象デバイスに適応させることができます。このようにして、アプリケーションの UI とパフォーマンスをテストできます。ただし、公開する前にアプリケーションを実際の対象デバイスでテストすることを強く推奨します。 個人、組織、知的財産を保護するため、アプリケーションのエンドユーザー ライセンス契約(EULA)を付加することを推奨します。 + +
アプリケーションのマニフェストに指定するアイコンとラベルは、アプリケーションのアイコンと名前としてユーザーに表示されるため、重要な要素です。アイコンとラベルは、デバイスの [[]ホーム] 画面や、[[]アプリケーションの管理]、[[]マイダウンロード] などに表示されます。また、公開サービスによってアイコンとラベルがユーザーに表示される可能性もあります。
+ +アイコンとラベルを指定するには、android:icon
と android:label
属性をマニフェストの <application>
要素に定義します。
アイコンのデザインについては、組み込みの Android アプリケーションのスタイルとできるだけ統一感を持たせてください。
+ +リリース時にはデバッグ機能を無効にし、デバッグおよびその他の不要なデータ/ファイルをアプリケーション プロジェクトから削除してください。
+android:debuggable="true"
属性をマニフェストの <application>
要素から削除します。アプリケーションをコンパイルする前に、アプリケーションにバージョン番号を定義しておく必要があります。定義するには、アプリケーションのマニフェスト ファイルの <manifest>
要素の android:versionCode
と android:versionName
属性の両方に適切な値を指定します。バージョン番号の設定は、全体的なアプリケーションアップグレードの計画を考慮して、慎重に検討してください。
これまでにリリースしたバージョンがある場合、最新のアプリケーションのバージョン番号を旧バージョンから増加させる必要があります。アプリケーションのマニフェスト ファイルの <manifest>
要素の android:versionCode
と android:versionName
属性の両方を適切な値を使用して増加する必要があります。
アプリケーションのバージョン情報を定義する方法は、Versioning Your Applicationsをご覧ください。
+ +ここまで準備作業をすべて読んで実行していれば、アプリケーションはコンパイルされ、署名の準備ができています。.apk の内部では、アプリケーションは適切にバージョン管理されており、上記のように余分なファイルや非公開データは削除されています。
+ +アプリケーションに署名する前に、適切な非公開キーがあることを確認する必要があります。非公開キーを取得(または生成)する方法については、適切な非公開キーの取得をご覧ください。
+ +適切な非公開キーを取得(または生成)したら、キーを使用して次の手順を実行します:
+ ++Maps API キーを取得する方法は、Maps API キーの取得(英語のみ) をご覧ください。
アプリケーションが Mapview 要素を使用する場合、アプリケーションを Google Maps サービスで登録し、Maps API キーを取得する必要があります。その後、MapView で Google Maps からデータを取得できるようになります。この処理を行うため、Maps サービスに署名証明書の MD5 フィンガープリントを提出します。
+ +開発中は、SDK ツールが生成したデバッグ キーを登録して一時的な Maps API キーを取得できます。ただし、アプリケーションを公開する前には、非公開キーに基づく新しい Maps API キーで登録する必要があります。
+ +アプリケーションが MapView 要素を使用する場合、次の点を理解することが重要です:
+ +android:apiKey
という特殊な属性に追加する必要があるからです。MapView オブジェクトをコードから直接インスタンス化している場合は、Maps API キーをコンストラクタのパラメータとして渡す必要があります。
+署名と非公開キーについては、アプリケーションへの署名をご覧ください。
+ + +前述のセクションで説明したアプリケーションの準備ができたら、アプリケーションをリリース用にコンパイルできます。
+ +非公開キーを使用してアプリケーションに署名します。アプリケーションに正しく署名することは、非常に重要です。詳細は、アプリケーションへの署名をご覧ください。
+ +コンパイルしたアプリケーションをリリースする前に、対象とする携帯端末(および可能ならば対象ネットワーク)上で徹底的にテストする必要があります。特に、UI 部分の MapView 要素がマップ データを正常に受信していることを確認してください。正常に受信していない場合、Maps API キーに登録するに戻って問題を解決してください。アプリケーションがサーバー側サービスを正しく利用できること、指定データまたは使用データを正しく処理できること、そして認証要件を正常に処理できることも確認してください。
+ +これらのテストが完了したら、アプリケーションを携帯端末ユーザーに公開する準備が整ったと言えるでしょう。
+ + diff --git a/docs/html/intl/ja/guide/publishing/versioning.jd b/docs/html/intl/ja/guide/publishing/versioning.jd new file mode 100644 index 0000000..bf86016 --- /dev/null +++ b/docs/html/intl/ja/guide/publishing/versioning.jd @@ -0,0 +1,100 @@ +page.title=アプリケーションのバージョニング +@jd:body + +バージョン管理のコンポーネントは、アプリケーションのアップグレード及びメンテナンスの計画を立てるのに重要です。
+ +Android システム自体は、アップグレードや互換性の制約の実施などのために、アプリケーション バージョン情報をアプリケーションに対して確認することはありません。代わりに、アプリケーションにおけるバージョン制約はユーザーまたはアプリケーション自体によって完全に実施されます。
+ +Android システムが確認を行うのは、アプリケーションによってマニフェストの minSdkVersion
属性に指定されたシステム バージョン互換性です。この属性によりアプリケーションは互換性を持つ最小システム API を指定できます。詳細は、最小システム API バージョンの指定をご覧ください。
+
+
アプリケーションのバージョン情報を定義するには、アプリケーションのマニフェスト ファイルで属性を設定します。2 つの属性を使用でき、常にこの両方に値を定義することが推奨されています:
+ +android:versionCode
- アプリケーション コードのバージョンを他のバージョンと相対的に示す整数値。
+
+この値は整数なので、その他のアプリケーションはプログラムでバージョンの値を評価して関係を確認できます(たとえば、このバージョンがアップグレードかダウングレードなのか、など)。任意の整数値を設定できますが、アプリケーションの後続のリリースでは、現在より大きな値を使用するようにしてください。システムではこのバージョン管理の基準を強制しませんが、後継リリースの値を増加させることは標準的です。
+ +通常、アプリケーションの最初のバージョンの versionCode を 1 に設定してリリースし、その後は各リリースについて、リリースがメジャー リリースであってもマイナー リリースであっても、値を単調増加させます。これは、android:versionCode
の値は、ユーザーに表示されるアプリケーション リリース バージョンと類似している必要性はないことを意味します。以下の android:versionName
をご覧ください。アプリケーションと公開サービスでは、このバージョンの値はユーザーには表示されません。
android:versionName
- アプリケーション コードのリリース バージョンを表す文字列値で、ユーザーに表示される値です。
+値は文字列なので、アプリケーション バージョンを「<major>.<minor>.<point>」といった文字列や、その他のタイプの絶対的または相対的バージョン ID として記述できます。
+ +android:versionCode
の場合と同様に、システムではこの値をアプリケーションでユーザーに表示する以外の目的で内部的に利用することはありません。公開サービスでは、ユーザーに表示するために android:versionName
値を取り出す可能性もあります。
これらのバージョン属性の両方をマニフェスト ファイルの <manifest>
要素で定義します。
ここに、<manifest>
要素の android:versionCode
と android:versionName
属性を示すマニフェストの例を示します。
+<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.example.package.name" + android:versionCode="2" + android:versionName="1.1"> + <application android:icon="@drawable/icon" android:label="@string/app_name"> + ... + </application> +</manifest> ++ +
この例では、android:versionCode
値は現在の .apk がこのアプリケーション コードの 2 番目のリリースを含んでいることを表し、これは android:codeName
文字列が示すようにマイナー後継リリースであることを示します。
Android フレームワークには、アプリケーションがシステムに別のアプリケーションのバージョン情報を問い合わせる API が用意されています。バージョン情報を取得するため、アプリケーションは {@link android.content.pm.PackageManager#getPackageInfo(java.lang.String, int)} +method of {@link android.content.pm.PackageManager PackageManager}.
を使用します。 + +アプリケーションが最低でも Android プラットフォームの特定のバージョンを必要とする場合、このバージョンを API レベルの ID としてアプリケーションのマニフェスト ファイルに指定できます。このようにすると、互換性のあるバージョンの Android システムを実行しているデバイスにのみアプリケーションをインストールできるようになります。
+ +最小システム バージョンをマニフェストに指定するには、次の属性を使用します:
+ +android:minSdkVersion
- Android プラットフォームのコード バージョンに対応する整数値。
+アプリケーションのインストールを準備する際に、システムはこの属性の値を確認して、システム バージョンと比較します。android:minSdkVersion
値がシステム バージョンよりも大きい場合、システムはアプリケーションのインストールを中止します。
この属性をマニフェストに指定しない場合、システムではアプリケーションがすべてのプラットフォーム バージョンと互換性があると仮定します。
アプリケーションに最小プラットフォーム バージョンを指定するには、<uses-sdk>
要素を <manifest>
の子として追加し、android:minSdkVersion
を属性として定義します。
詳細は、Android System Image 1.1 Version Notes もご覧ください。
diff --git a/docs/html/intl/ja/guide/topics/fundamentals.jd b/docs/html/intl/ja/guide/topics/fundamentals.jd new file mode 100644 index 0000000..247d076 --- /dev/null +++ b/docs/html/intl/ja/guide/topics/fundamentals.jd @@ -0,0 +1,922 @@ +page.title=開発の基礎 +@jd:body + +
+Android アプリケーションはすべて Java プログラミング言語で記述します。コンパイル済みの Java コード(およびそのアプリケーションに必要なすべてのデータやリソース ファイル)は、aapt
ツールを使用して Android パッケージにバンドルします。Android パッケージは、拡張子が {@code .apk} のアーカイブ ファイルです。ユーザーは、このファイルをデバイスにダウンロードして利用します。つまり、Android パッケージは、アプリケーションをモバイル デバイスに配布およびインストールするための媒体として機能します。1 つの {@code .apk} ファイルに含まれているすべてのコードが、1 つのアプリケーションと見なされます。
+
+各 Android アプリケーションは、以下に示すさまざまな方法で他のアプリケーションから隔離されています: +
+ ++2 つのアプリケーションで同じユーザー ID を共有することもできます。その場合は、それぞれのアプリケーションのファイルを相互に認識できます。システム リソースを節約するため、同じ ID のアプリケーションで同じ VM を共有し、同じ Linux プロセスで実行することも可能です。 +
+ + ++Android の大きな特長の 1 つは、許可されていれば、あるアプリケーションから別のアプリケーションの要素を利用できる点です。たとえば、開発中のアプリケーションで画像の一覧をスクロール表示したい場合、他のアプリケーションで開発済みの適切なスクローラがあり、その利用が許可されていれば、独自に開発しなくてもそのスクローラを利用できます。アプリケーションに他のアプリケーションのコードを組み込んだり、リンクを設定したりする必要はありません。必要になった時点で、他のアプリケーションの一部分を開始するだけです。 +
+ ++この仕組みが機能するには、アプリケーション プロセスの一部分を必要に応じて開始でき、その部分の Java オブジェクトをインスタンス化できなくてはなりません。そのため、Android アプリケーションには、他のシステムで動作するアプリケーションでよく使用されるような、アプリケーション全体にアクセスするための単一のエントリ ポイント(たとえば {@code main()} 関数)はありません。代わりに、システムが必要に応じてインスタンス化して実行できるコンポーネントで構成されます。コンポーネントには以下の 4 つのタイプがあります: +
+ ++アプリケーションは、1 つのアクティビティで構成することも、上記のSMS アプリケーションのように複数のアクティビティで構成することもできます。どのようなアクティビティがいくつ必要になるかは、アプリケーションやその設計に応じて異なります。通常は、アクティビティのうちのいずれかを最初のアクティビティとして指定し、ユーザーがアプリケーションを起動したときに表示します。あるアクティビティから別のアクティビティに移動するには、現在のアクティビティから次のアクティビティを開始します。 +
+ ++各アクティビティには、それを表示するためのデフォルトのウィンドウが割り当てられます。通常はウィンドウを画面全体に表示しますが、画面より小さいウィンドウを他のウィンドウの前面に表示することもできます。アクティビティに、新たなウィンドウを追加することも可能です。たとえば、アクティビティの途中でユーザーの応答を要求するポップアップ ダイアログを表示したり、ユーザーが画面上の特定のアイテムを選択したときに別ウィンドウで重要な情報を表示したりできます。 +
+ ++ウィンドウの視覚的なコンテンツは、ビュー({@link android.view.View} 基本クラスの派生オブジェクト)の階層として提供されます。各ビューは、ウィンドウ内の特定の矩形領域を制御します。親ビューは、その子となるビューで構成され、それらの子ビューのレイアウトを決定します。リーフ ビュー(階層の最下位に位置するビュー)は、そのビューが制御する矩形領域に表示され、その領域でのユーザーのアクションに対して応答します。つまり、ビューはアクティビティとユーザーが対話する場所です。たとえば、ビューに小さな画像を表示し、ユーザーがその画像をタップしたら何らかのアクションを開始することもできます。Android には、ボタン、テキスト フィールド、スクロール バー、メニュー アイテム、チェックボックスなど、さまざまなビューがあらかじめ用意されています。 +
+ +
+ビューの階層は、{@link android.app.Activity#setContentView Activity.setContentView()}
メソッドを使用してアクティビティのウィンドウ内に配置します。コンテンツ ビューは、階層のルートとなる View オブジェクトです(ビューおよびその階層について詳しくはUser Interface のドキュメントをご覧ください)。
+
+典型的な例としては、プレイリストの曲を再生するメディア プレーヤーが挙げられます。プレーヤー アプリケーションは、ユーザーが曲を選んで再生するための 1 つ以上のアクティビティで構成することが予想されますが、ユーザーはプレーヤーを離れて別の操作に移った後も曲を聞いていたいと考えられることから、曲の再生自体をアクティビティで処理するわけにはいきません。音楽の再生を続けるには、メディア プレーヤー アクティビティから、バックグラウンドで実行するサービスを開始します。音楽再生サービスは、それを開始したアクティビティが画面上に見えなくなった後もそのまま実行されます。 +
+ ++また、実行中のサービスに接続(バインド)することもできます(実行されていない場合はそのサービスを開始することも可能です)。接続中は、サービスが公開しているインターフェースを使ってサービスと対話できます。音楽再生サービスであれは、このインターフェースを使って一時停止、巻き戻し、停止、再生の再開などの操作を実行できるようにします。 +
+ ++アクティビティや他のコンポーネントと同様に、サービスもアプリケーション プロセスのメイン スレッドで実行します。したがって、サービスによって他のコンポーネントやユーザー インターフェースの実行を妨げられることはなく、時間がかかるタスク(たとえば曲の再生)については、通常は別のスレッドを生成して処理します。詳しくは、プロセスとスレッドをご覧ください。 +
+アプリケーションでは、重要と思われるすべての連絡に応答できるよう、ブロードキャスト レシーバをいくつでも設定できます。すべてのレシーバは、{@link android.content.BroadcastReceiver} 基本クラスの拡張です。 +
+ ++ブロードキャスト レシーバがユーザー インターフェースを表示することはありません。ただし、受信した情報への応答としてアクティビティを開始したり、{@link android.app.NotificationManager} を使用してユーザーにアラートを送信したりすることはあります。通知の際には、バックライトを点滅させる、バイブレーションを起動する、音を鳴らすなど、さまざまな方法でユーザーの注意を喚起できます。通常は、ステータス バーに永続アイコンを表示し、ユーザーがこれを開いてメッセージを取得できるようにします。 +
+コンテンツ プロバイダの使用方法について詳しくは、Content Providersのドキュメントをご覧ください。 +
+Android では、特定のコンポーネントで処理すべきリクエストがあると、そのコンポーネントのアプリケーション プロセスが実行中かどうかを確認(必要に応じてプロセスを開始)し、そのコンポーネントの適切なインスタンスが利用可能かどうかを確認(必要に応じてインスタンスを作成)します。 +
+ + ++コンテンツ プロバイダは、ContentResolver からのリクエストの対象になるとアクティブ化されます。それ以外の 3 つのコンポーネント(アクティビティ、サービス、ブロードキャスト レシーバ)は、インテントと呼ばれる非同期メッセージによってアクティブ化されます。インテントは、メッセージのコンテンツを保持する {@link android.content.Intent} オブジェクトです。アクティビティやサービスの場合の Intent オブジェクトの主な役割は、リクエストされているアクションを指名し、その対象となるデータの URI を指定することです。たとえば、ユーザーに画像を表示するためのリクエストや、ユーザーにテキストを編集させるリクエストをアクティビティに伝達できます。ブロードキャスト レシーバの場合は、Intent オブジェクトがこれから通知を行うアクションを指名します。たとえば、カメラのボタンが押されたことを、関係のあるブロードキャスト レシーバに通知できます。 +
+ ++以下に示すように、コンポーネントのタイプごとに別々のアクティブ化メソッドが用意されています: +
+ +{@link android.content.Context#startActivity
+Context.startActivity()}
または {@link
+android.app.Activity#startActivityForResult
+Activity.startActivityForResult()}
に渡します。応答アクティビティで {@link android.app.Activity#getIntent getIntent()}
メソッドを呼び出すと、最初にそのアクティビティが起動されたときのインテントの内容を確認できます。Android によってアクティビティの {@link
+android.app.Activity#onNewIntent onNewIntent()}
メソッドが呼び出され、アクティビティが後続のインテントに渡されます。
+
+
+多くの場合、アクティビティから次のアクティビティを開始します。開始するアクティビティから結果が返される場合は、{@code startActivity()} ではなく {@code startActivityForResult()} を呼び出します。たとえば、ユーザーに写真を選択させるアクティビティを開始する場合は、ユーザーによって選択された写真が返されるかもしれません。結果は、呼び出し側のアクティビティの {@link android.app.Activity#onActivityResult
+onActivityResult()}
メソッドに渡した Intent オブジェクトで返されます。
+
サービスを開始する(または実行中のサービスに新しい指示を与える)には、{@link
+android.content.Context#startService Context.startService()}
に Intent オブジェクトを渡します。Android により、サービスの {@link android.app.Service#onStart
+onStart()}
メソッドが呼び出されて Intent オブジェクトが渡されます。
+同様に、インテントを {@link
+android.content.Context#bindService Context.bindService()}
に渡すと、呼び出し側のコンポーネントと対象となるサービスの間の継続中の接続を確立できます。サービスは、{@link android.app.Service#onBind onBind()}
呼び出しで Intent オブジェクトを受け取ります(サービスがまだ開始されていない場合は、必要に応じて {@code bindService()} で開始できます)。たとえば、上で例に挙げた音楽再生サービスとの接続を確立するアクティビティを使用して、ユーザーが再生を操作するための手段(ユーザー インターフェース)を提供できます。アクティビティで {@code bindService()} を呼び出して接続を確立してから、サービスに定義されているメソッドを呼び出して再生を操作します。
+
+サービスのバインドについては、後ほどリモート プロシージャ コールのセクションで詳しく説明します。 +
+アプリケーションでブロードキャストを開始するには、{@link
+android.content.Context#sendBroadcast(Intent) Context.sendBroadcast()}
、{@link android.content.Context#sendOrderedBroadcast(Intent, String)
+Context.sendOrderedBroadcast()}
、{@link
+android.content.Context#sendStickyBroadcast Context.sendStickyBroadcast()}
などのメソッドのいずれかのバリエーションに Intent オブジェクトを渡します。Android によって {@link
+android.content.BroadcastReceiver#onReceive onReceive()}
メソッドが呼び出され、関係のあるすべてのブロードキャスト レシーバにインテントが配信されます。
+インテント メッセージについて詳しくは、Intents and Intent Filters をご覧ください。 +
+ + ++コンテンツ プロバイダは、ContentResolver からのリクエストに応答している間のみアクティブになります。ブロードキャスト レシーバは、ブロードキャスト メッセージに応答している間のみアクティブになります。つまり、これらのコンポーネントを明示的に終了させる必要はありません。 +
+ ++一方、アクティビティはユーザー インターフェースを提供します。長い時間をかけてユーザーと会話するためのものであり、待機状態の間も、会話が続いてきる限りはアクティブなままになっている可能性があります。同様に、サービスも長い間実行されたままになる可能性があります。Android には、アクティビティとサービスを以下のような規則的な方法で終了させるためのメソッドが用意されています: +
+ +{@link android.app.Activity#finish finish()}
メソッドを呼び出します。あるアクティビティから {@code startActivityForResult()} で開始した別のアクティビティは、{@link android.app.Activity#finishActivity finishActivity()}
を呼び出して終了させることができます。{@link android.app.Service#stopSelf stopSelf()}
メソッドを呼び出すか、{@link android.content.Context#stopService Context.stopService()}
を呼び出すことで停止できます。+コンポーネントが、既に利用されていない場合や、Android がよりアクティブな他のコンポーネントにメモリを割り当てる必要がある場合は、システムがコンポーネントを終了させることもあります。このような状況およびその影響については、コンポーネントのライフサイクルで詳しく説明します。 +
+ + ++アプリケーション コンポーネントを開始するには、Android がそのコンポーネントの存在を認識している必要があります。アプリケーションのコンポーネントは、マニフェスト ファイルで宣言します。このファイルは、アプリケーションのコード、ファイル、リソースなどとともに Android パッケージ({@code .apk} ファイル)にバンドルされます。 +
+ ++マニフェストは構造化された XML ファイルで、どのアプリケーションでも常に AndroidManifest.xml という名前になります。アプリケーション コンポーネントの宣言以外にも、アプリケーションをリンクさせる必要のあるライブラリ(デフォルトの Android ライブラリを除く)の指定や、アプリケーションに付与されるべき権限の指定などにも使用します。 +
+ ++しかし、マニフェストの最も重要な役割は、アプリケーションのコンポーネントに関する情報を Android に提供することです。たとえば、アクティビティを次のように宣言できます: +
+ +<?xml version="1.0" encoding="utf-8"?> +<manifest . . . > + <application . . . > + <activity android:name="com.example.project.FreneticActivity" + android:icon="@drawable/small_pic.png" + android:label="@string/freneticLabel" + . . . > + </activity> + . . . + </application> +</manifest>+ +
+<activity>
要素の {@code name} 属性は、そのアクティビティを実装する {@link android.app.Activity} サブクラスを指名します。{@code icon} および {@code label} 属性には、ユーザーに対して表示するアイコンやラベルが保持されているリソース ファイルを指定します。
+
+その他のコンポーネントも、サービスは <service>
要素、ブロードキャスト レシーバは <receiver>
要素、コンテンツ プロバイダは <provider>
要素を使用して同じような方法で宣言します。マニフェストに宣言されていないアクティビティ、サービス、およびコンテンツ プロバイダは、システムから認識できないため実行されることはありません。ただし、ブロードキャスト レシーバの場合は、マニフェストで宣言する方法と、コード内で {@link android.content.BroadcastReceiver} オブジェクトとして動的に作成し、{@link android.content.Context#registerReceiver Context.registerReceiver()}
を呼び出してシステムに登録する方法があります。
+
+マニフェスト ファイルの作成方法について詳しくは、The AndroidManifest.xml Fileをご覧ください。 +
+ + ++Intent オブジェクトでは、対象とするコンポーネントを明示的に指名できます。明示的に指名されている場合、Android はマニフェスト ファイル内の宣言に基づいてコンポーネントを特定してアクティブにします。一方、明示的に指名されていない場合は、そのインテントに応答する上で最適なコンポーネントが選択されます。方法としては、Intent オブジェクトを、その対象となりうるコンポーネントのインテント フィルタと照合します。コンポーネントのインテント フィルタは、そのコンポーネントで処理できるインテントの種類を示します。これもコンポーネントに関する重要な情報の 1 つなので、マニフェスト ファイルで宣言します。次に、上に示した例を拡張して 2 つのインテント フィルタを追加したアクティビティを示します: +
+ +<?xml version="1.0" encoding="utf-8"?> +<manifest . . . > + <application . . . > + <activity android:name="com.example.project.FreneticActivity" + android:icon="@drawable/small_pic.png" + android:label="@string/freneticLabel" + . . . > + <intent-filter . . . > + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + <intent-filter . . . > + <action android:name="com.example.project.BOUNCE" /> + <data android:mimeType="image/jpeg" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + . . . + </application> +</manifest>+ +
+この例の 1 つ目のフィルタは、アクション「{@code android.intent.action.MAIN}」とカテゴリ「{@code android.intent.category.LAUNCHER}」を組み合わせた一般的なフィルタです。このフィルタは、アプリケーション ランチャ(ユーザーがデバイス上で起動できるアプリケーションを一覧表示した画面)に、このアクティビティを表示する必要があることを示しています。つまり、このアクティビティはアプリケーションへのエントリ ポイントとして機能し、ユーザーがランチャでそのアプリケーションを選択したときに最初に表示されるということです。 +
+ ++2 つ目のフィルタでは、アクティビティが特定のタイプのデータに対して実行できるアクションを宣言しています。 +
+ ++コンポーネントにはインテント フィルタをいくつでも指定でき、それぞれのフィルタで別々の機能を宣言できます。フィルタが 1 つも指定されていないコンポーネントは、そのコンポーネントが対象として明示的に指名されているインテントでのみアクティブにできます。 +
+ ++コード内で作成して登録したブロードキャスト レシーバの場合、インテント フィルタは {@link android.content.IntentFilter} オブジェクトとして直接インスタンス化されます。それ以外の全てのフィルタは、マニフェストで設定します。 +
+ ++インテント フィルタについて詳しくは、Intents and Intent Filters をご覧ください。 +
+ + ++既に説明したように、あるアクティビティから別のアクティビティを開始することができます。これには、別のアプリケーションで定義されているアクティビティも含まれます。たとえば、ユーザーに特定の場所の地図を表示するとします。そのためのアクティビティは既に存在しているので、現在のアクティビティで必要な情報を Intent オブジェクトに格納して {@code startActivity()} に渡すだけで、マップ ビューアに地図を表示できます。ユーザーが [戻る] キーを押すと、画面に元のアクティビティが再表示されます。 +
+ ++この場合、マップ ビューアは別のアプリケーションで定義されており、そのアプリケーションのプロセスで実行されていますが、ユーザーにとってはマップ ビューアが元のアプリケーションの一部であるかのように感じられます。Android では、両方のアクティビティを同じタスクに組み込むことで、このようなユーザー エクスペリエンスを実現できます。簡単に言えば、ユーザーが 1 つの「アプリケーション」と感じるものがタスクです。関連するアクティビティをスタックにまとめたものがタスクです。スタック内のルート アクティビティは、タスクを開始するアクティビティです。通常であれば、ユーザーがアプリケーション ランチャで選択するアクティビティがこれに相当します。スタックの最上位にあるアクティビティは、ユーザーのアクションの焦点となっている実行中のアクティビティです。あるアクティビティから別のアクティビティを開始すると、そのアクティビティが新たにスタックにプッシュされて実行中のアクティビティになります。1 つ前のアクティビティはスタック内に残されています。ユーザーが [[]戻る] キーを押すと、現在のアクティビティがスタックからポップされ、1 つ前のアクティビティが実行中のアクティビティとして再開されます。 +
+ ++スタックはオブジェクトを保持します。したがって、同じ Activity サブクラスのインスタンス(たとえばマップ インスタンス)を複数開くと、それぞれのインスタンスが別々のエントリになります。スタック内のアクティビティは、プッシュまたはポップされるのみで再配置されることはありません。 +
+ ++タスクはアクティビティのスタックであり、マニフェスト ファイル内のクラスや要素ではありません。したがって、アクティビティと無関係にタスクの値を設定することはできません。タスクの値は、ルート アクティビティでまとめて設定します。たとえば、次のセクションでは「タスクの親和性」について説明しますが、値はタスクのルート アクティビティの親和性のセットから読み込まれます。 +
+ ++タスク内のアクティビティは、1 つのユニットとして一緒に移動します。タスク全体(アクティビティ スタック全体)をフォアグラウンドに移動したり、バックグラウンドに移動したりできます。たとえば、現在のタスクは 4 つのアクティビティからなるスタックで、現在のアクティビティの下にアクティビティが 3 つあるとします。ここで、ユーザーが [ホーム] キーを押してアプリケーション ランチャに移動し、新しいアプリケーション(実際には新しいタスク)を選択したとします。すると、現在のタスクはバックグラウンドに移動し、新しいタスクのルート アクティビティが表示されます。しばらくして、ユーザーがホーム画面に戻り 1 つ前のアプリケーション(タスク)を選択すると、そのタスクがスタック内の 4 つのアクティビティとともにフォアグラウンドに移動します。ここでユーザーが [戻る] キーを押しても、中断したばかりのアプリケーション(1 つ前のタスクのルート アクティビティ)は表示されません。代わりに、スタックの最上位のアクティビティがポップされ、同じタスクの 1 つ前のアクティビティが表示されます。 +
+ +
+アクティビティとタスクの動作としては、ここで説明した動作がデフォルトです。ただし、この動作のほとんどの要素は変更可能です。タスクとアクティビティの関連付けやタスク内でのアクティビティの動作は、アクティビティを開始した Intent オブジェクトのフラグ セットと、マニフェストに指定されているアクティビティの <activity>
要素の属性セットとの相互作用によって決まります。リクエスト側と応答側の両方が動作に影響を及ぼします。
+
+この点において、主に使用する Intent フラグは以下のとおりです: + +
{@code FLAG_ACTIVITY_NEW_TASK}
{@code FLAG_ACTIVITY_CLEAR_TOP}
{@code FLAG_ACTIVITY_RESET_TASK_IF_NEEDED}
{@code FLAG_ACTIVITY_SINGLE_TOP}
+また、主に使用する {@code <activity>} 属性は以下のとおりです: + +
{@code taskAffinity}
{@code launchMode}
{@code allowTaskReparenting}
{@code clearTaskOnLaunch}
{@code alwaysRetainTaskState}
{@code finishOnTaskLaunch}
+以降のセクションでは、これらのフラグや属性の役割、相互作用の仕組み、使用する際の留意事項などについて説明します。 +
+ + ++デフォルトでは、アプリケーション内のすべてのアクティビティは相互に親和性があり、すべてのアクティビティができる限り同じタスクに属そうとします。ただし、{@code <activity>} 要素の {@code taskAffinity} 属性を使用して、アクティビティごとに個別の親和性を設定することもできます。つまり、別々のアプリケーションで定義されているアクティビティで親和性を共有したり、同じアプリケーションで定義されているアクティビティに別々の親和性を割り当てたりできるということです。親和性が作用する状況は 2 つあります。1 つはアクティビティを起動する Intent オブジェクトに {@code FLAG_ACTIVITY_NEW_TASK} フラグが含まれている場合、もう 1 つはアクティビティの {@code allowTaskReparenting} 属性が "{@code true}" に設定されている場合です。 +
+ +{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}
フラグallowTaskReparenting
属性+ユーザーから見て複数の「アプリケーション」が 1 つの {@code .apk} ファイルに含まれている場合は、それぞれのアプリケーションに関連付けられているアクティビティに別々の親和性を割り当てることをおすすめします。 +
+ + +
+launchMode
属性の {@code <activity>} 要素には、以下の 4 種類の起動モードを割り当てることができます:
+
"{@code standard}"(デフォルト モード)
"{@code singleTop}"
"{@code singleTask}"
"{@code singleInstance}"
+これらのモードは、それぞれが以下の 4 つの点で異なります: +
+ +{@link android.content.Context#startActivity startActivity()}
を呼び出した)タスクに保持されます。ただし、Intent オブジェクトに {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}
フラグが含まれている場合は、前のセクション親和性と新しいタスクで説明したとおり、別のタスクが選択されます。
+
++一方、"{@code singleTask}" および "{@code singleInstance}" モードの場合は、アクティビティが常にタスクのルート アクティビティになります。タスクは定義されており、他のタスクの一部として起動されることはありません。 +
+ +アクティビティのインスタンスを複数生成できるか。"{@code standard}" または "{@code singleTop}" アクティビティは複数回インスタンス化できます。それらのインスタンスを複数のタスクに割り当てることも、特定のタスクに同じアクティビティの複数のインスタンスを割り当てることも可能です。 +
+ ++一方、"{@code singleTask}" および "{@code singleInstance}" アクティビティのインスタンスは 1 つに制限されます。これらのアクティビティはタスクのルートに当たります。したがって、これらのタスクの複数のインスタンスがデバイス上に同時に存在することはないということになります。 +
+ +インスタンスのタスクに他のアクティビティを含めることができるか。"{@code singleInstance}" アクティビティは、そのタスク内の唯一のアクティビティとして単独で動作します。ここから別のアクティビティを開始した場合、そのアクティビティは起動モードに関係なく、あたかもインテントに {@code FLAG_ACTIVITY_NEW_TASK} フラグが含まれているかのように別のタスクで起動します。"{@code singleInstance}" モードと "{@code singleTask}" モードは、これ以外の点ではまったく同じです。
+ ++他の 3 つのモードでは、タスクに複数のアクティビティを割り当てることができます。"{@code singleTask}" アクティビティは、常にタスクのルート アクティビティになりますが、同じタスクに割り当てることになる別のアクティビティを開始することができます。"{@code standard}" および "{@code singleTop}" アクティビティのインスタンスは、スタック内のどの位置にでも配置できます。 +
+たとえば、タスクのアクティビティ スタックに、ルート アクティビティ A とアクティビティ B、C、D が含まれているとします。スタック内のアクティビティの順序は A-B-C-D で D が最上位です。ここに、アクティビティのタイプが D のインテントが届きます。D の起動モードがデフォルトの "{@code standard}" である場合は、そのクラスの新しいインスタンスが起動し、スタックは A-B-C-D-D となります。しかし、D の起動モードが "{@code singleTop}" であれば、スタックの最上位は D なので、新しいインテントは既存のインスタンスによって処理されるはずです。したがって、スタックは A-B-C-D のままとなります。 +
+ ++一方、届いたインテントのアクティビティ タイプが B だった場合は、B のモードが "{@code standard}" であっても "{@code singleTop}"であっても B の新しいインスタンスが起動します。これは B がスタックの最上位ではないためで、結果としてスタックは A-B-C-D-B となります。 +
+ ++"{@code singleTask}" または "{@code singleInstance}" アクティビティの場合は、既に説明したとおり同時に複数のインスタンスが存在することはないため、インスタンスは常に新しいインテントを処理することになります。"{@code singleInstance}" アクティビティはスタック内の唯一のアクティビティであるため、常にスタックの最上位、つまりインテントを処理する位置にあります。一方、"{@code singleTask}" アクティビティは、スタック内の上位に他のアクティビティがある場合とない場合があります。上位にアクティビティがある場合、インテントを処理する位置にはないため、そのインテントはドロップされます(インテントがドロップされたとしても、そのインテントが届いたことによって、タスクがフォアグラウンドに移ったままの状態になります)。 +
+
+既存のアクティビティで新しいインテントを処理することになった場合は、{@link android.app.Activity#onNewIntent onNewIntent()}
の呼び出しによって Intent オブジェクトがアクティビティに渡されます(最初にアクティビティを開始したインテント オブジェクトは {@link android.app.Activity#getIntent getIntent()}
を呼び出して取得できます)。
+
+なお、新しいインテントを処理するためにアクティビティの新しいインスタンスが作成された場合、ユーザーは [[]戻る] キーを押して 1 つ前の状態(1 つ前のアクティビティ)に戻ることができます。しかし、アクティビティの既存のインスタンスで新しいインテントを処理する場合は、[[]戻る] キーを押しても、新しいインテントが届く前にそのインスタンスで処理していた作業に戻ることはできません。 +
+ +
+起動モードについて詳しくは、<activity>
要素の説明をご覧ください。
+
+ユーザーがタスクを長時間放置すると、タスクのルート アクティビティを除くすべてのアクティビティがクリアされます。ユーザーがタスクに戻ると、タスクは以前のように表示されますが、残っているのは最初のアクティビティだけです。つまり、一定の時間が経過していればユーザーは以前の作業を放棄していて、新しい作業をするためにそのタスクに戻ってきたと考えるわけです。 +
+ ++これがデフォルトです。この動作を変更したい場合は、以下のアクティビティ属性を使用します: +
+ +alwaysRetainTaskState
属性clearTaskOnLaunch
属性finishOnTaskLaunch
属性
+アクティビティをスタックから削除する方法は他にもあります。Intent オブジェクトに {@link
+android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP FLAG_ACTIVITY_CLEAR_TOP}
フラグが含まれており、そのインテントを処理すべきタイプのアクティビティのインスタンスが対象タスクのスタック内に存在する場合は、そのインスタンスがスタックの最上位になってインテントに応答できるよう、それより上位のアクティビティはすべてクリアされます。指定されたアクティビティの起動モードが "{@code standard}" である場合は、そのアクティビティもスタックから削除され、新しいインスタンスが起動してインテントを処理します。起動モード "{@code standard}" では、新しいインテントを処理する際、常に新しいインスタンスが作成されるためです。
+
+{@code FLAG_ACTIVITY_CLEAR_TOP} は、ほとんどの場合 {@code FLAG_ACTIVITY_NEW_TASK} と組み合わせて使用します。これらのフラグを組み合わせると、別のタスクに既に存在しているアクティビティを探し、それをインテントに応答できる位置に配置できます。 +
+ + ++アクティビティをタスクのエントリ ポイントとして設定するには、アクションとして "{@code android.intent.action.MAIN}"、カテゴリとして "{@code android.intent.category.LAUNCHER}" を指定したインテント フィルタをアクティビティに追加します(このタイプのフィルタの例については、インテント フィルタをご覧ください)。このタイプのフィルタを追加すると、アクティビティのアイコンとラベルがアプリケーション ランチャに表示されます。これにより、ユーザーがタスクを起動するための手段を提供できるだけでなく、起動後はいつでもそのタスクに戻れるようにすることができます。 +
+ ++この 2 番目の機能、つまりユーザーがいったんタスクを離れても後で戻ることができるようにする点が重要です。この理由から、アクティビティに {@code MAIN} と {@code LAUNCHER} フィルタが指定されている場合は、必ずタスクが開始される起動モード("{@code singleTask}" または "{@code singleInstance}")を使用する必要があります。たとえば、このフィルタを指定しなかった場合を考えてみましょう。インテントが "{@code singleTask}" アクティビティを起動し、新しいタスクが開始され、ユーザーがしばらくの間このタスクで作業を行います。その後、ユーザーが [ホーム] キーを押したとします。ホーム画面が表示され、先ほどのタスクはバックグラウンドに移動します。しかし、このタスクはアプリケーション ランチャには表示されていないため、ユーザーがタスクに戻るための手段がありません。 +
+ ++{@code FLAG_ACTIVITY_NEW_TASK} フラグにも、これと同じような難しさがあります。このフラグを指定したアクティビティでは、新しいタスクを開始した後にユーザーが [ホーム] キーを押してそのタスクを離れた場合に備え、タスクに戻るための手段を用意しておく必要があります。一部のエンティティ(たとえば通知マネージャ)は、アクティビティを常に外部タスクとして開始します。エンティティの一部として開始することはないため、{@code startActivity()} に渡すインテントには必ず {@code FLAG_ACTIVITY_NEW_TASK} を指定します。外部エンティティから呼び出すことのできるアクティビティでこのフラグが使用されている可能性がある場合は、開始されたタスクにユーザーが戻るための手段を別途提供するようにしてください。 +
+ ++ユーザーがアクティビティに戻ることができるようにしない場合は、{@code <activity>} 要素の {@code finishOnTaskLaunch} を "{@code true}" に設定します。詳しくは、スタックのクリアをご覧ください。 +
+ + ++Android では、最初のアプリケーション コンポーネントを実行する必要が生じると、そのための Linux プロセスを単一の実行スレッドで開始します。デフォルトでは、アプリケーションのすべてのコンポーネントがそのプロセスとスレッドで実行されます。 +
+ ++ただし、コンポーネントが他のプロセスで実行されるようにしたり、特定のプロセスに使用する追加スレッドを生成したりすることも可能です。 +
+ + ++コンポーネントを実行するプロセスは、マニフェスト ファイルで管理します。コンポーネントの各要素({@code <activity>}、{@code <service>}、{@code <receiver>}、および {@code <provider>})には {@code process} 属性があり、そのコンポーネントをどのプロセスで実行すべきかを指定できるようになっています。これらの属性の設定によって、それぞれのコンポーネントを専用のプロセスで実行したり、一部のコンポーネントだけでプロセスを共有したりできます。また、別々のアプリケーションのコンポーネントが、同じプロセスで実行されるように設定することもできます。この場合は、それらのアプリケーションが同じ Linux ユーザー ID を共有し、同じ認証機関によって署名されている必要があります。{@code <application>} 要素にも {@code process} 属性があり、すべてのコンポーネントに適用されるデフォルト値を設定できます。 +
+ +
+すべてのコンポーネントは指定されたプロセスのメイン スレッドでインスタンス化され、コンポーネントに対するシステム コールはそのスレッドからディスパッチされます。1 つのインスタンスに対して、複数のスレッドが作成されることはありません。したがって、システム コールに応答するメソッド(たとえば、後ほどコンポーネント ライフサイクルで説明するライフサイクル通知や、ユーザーのアクションを報告する {@link android.view.View#onKeyDown View.onKeyDown()}
のようなメソッド)は、常にそのプロセスのメイン スレッドで実行されます。つまり、コンポーネントがシステムから呼び出されたときに、プロセス内の他のコンポーネントの実行を妨げないよう、実行に時間がかかる処理や他の妨げになることの多い処理(ネットワーク処理、ループ計算など)をできる限り避ける必要があるということです。時間がかかる処理には別のスレッドを生成できます。詳しくは、次のスレッド セクションをご覧ください。
+
+状況によっては、Android がプロセスを終了させるべきと判断する場合があります。たとえば、メモリが不足してきた場合や、他のプロセスでユーザーにすばやく応答する必要がある場合です。プロセスが終了すると、そのプロセス内で実行されているアプリケーション コンポーネントは破棄されます。それらのコンポーネントで処理する作業がもう一度発生すると、そのためのプロセスが再び開始されます。 +
+ ++Android では、どのプロセスを終了させるかを判断するため、ユーザーにとっての相対的な重要度を重み付けして管理します。たとえば、アクティビティがまだ画面に表示されているプロセスを終了させるよりも、アクティビティが画面に表示されていないプロセスを終了させる方が合理的です。したがって、プロセスを終了させるかどうかは、そのプロセスで実行されているコンポーネントの状態に応じて判断されるということです。コンポーネントの状態については、後ほどコンポーネントのライフサイクルで詳しく説明します。 +
+ + ++アプリケーションを単一のプロセスに限定したとしても、バックグラウンドでの処理にスレッドが必要になることはよくあります。ユーザー インターフェースはユーザーのアクションに対して常にすばやく応答できなければならないため、アクティビティをホストするスレッドで、ネットワーク ダウンロードのような時間のかかる処理を一緒にホストしないようにする必要があります。すぐに完了しない可能性のあるすべての処理は、別のスレッドに割り当てるようにしてください。 +
+ ++スレッドは、標準の Java {@link java.lang.Thread} オブジェクトを使用してコード内で作成します。Android には、スレッドを管理するための便利なクラスが数多く用意されています。たとえば、スレッド内でメッセージ ループを実行するための {@link android.os.Looper}、メッセージを処理するための {@link android.os.Handler}、メッセージ ループでスレッドを設定するための {@link android.os.HandlerThread} などがあります。 +
+ + ++Androidは軽量な仕組みのリモート・プロシージャ・コール (RPC) を採用しています。RPC とは、メソッドをローカルで呼び出しますが、実行はリモート(別のプロセス)で行い、その結果を呼び出し側に返します。そのためには、メソッド呼び出しとそれに付随するデータをオペレーティングシステムが解釈できるレベルまで分解してから、それらをローカルのプロセスとアドレス空間からリモートのプロセスとアドレス空間に転送し、リモートで呼び出しを再構築する必要があります。戻り値は、反対方向に転送しなければなりません。Android にはこの処理を行うためのコードがすべて用意されているため、RPC インターフェースを定義して実装するだけで RPC を利用できます。 +
+ ++RPC インターフェースに含めることができるのはメソッドのみです。すべてのメソッドは、戻り値がない場合でも同期的に実行されます(つまり、リモート メソッドが完了するまでローカル メソッドがブロックされます)。 +
+ +
+このメカニズムを簡単に説明すると次のようになります。まず、シンプルなインターフェース定義言語(IDL)を使用して、実装したい RPC インターフェースを宣言します。aidl
ツールにより、RPC インターフェースの宣言から Java インターフェース定義が生成されます。この定義は、ローカルとリモートの両方のプロセスで使用する必要があります。定義には、次の図に示すように 2 つの内部クラスが含まれています:
+
+ +
+ ++これらの内部クラスには、IDL で宣言したインターフェースのリモート プロシージャ コールを管理するために必要なコードがすべて含まれています。どちらの内部クラスも {@link android.os.IBinder} インターフェースを実装します。一方の内部クラスは、ローカルのシステムで内部的に使用しますが、記述するコードでは無視しても構いません。もう一方の内部クラスはスタブと呼ばれ、{@link android.os.Binder} クラスを拡張します。スタブには、IPC(プロセス間通信)呼び出しを発生させるための内部コードに加え、IDL で宣言した RPC インターフェース内のメソッドの宣言が含まれます。これらのメソッドを実装するには、図に示すようにスタブをサブクラス化します。2つの内部クラスのうちの一方は、システムがローカルかつ内部的に使用するので、開発者が記述するコードでは無視してかまいません。... リモート側では、図のようにスタブをサブクラス化して、これらのメソッドを実装する必要があります。 +
+ ++ 通常、リモート プロセスはサービスで管理します。サービスなら、プロセスや他のプロセスへの接続に関する情報をシステムに伝えることができるからです。サービスには、{@code aidl} ツールで生成されたインターフェース ファイルと、RPC メソッドを実装するスタブ サブクラスの両方を持たせることになります。サービスのクライアントには、{@code aidl} ツールで生成されたインターフェース ファイルのみを持たせます。 +
+ ++以下に、サービスとそのクライアントの間の接続がどのように設定されるかを示します: +
+ +{@link android.content.ServiceConnection#onServiceConnected
+onServiceConnected()}
および{@link android.content.ServiceConnection#onServiceDisconnected
+onServiceDisconnected()}
メソッドが実装されているため、リモート サービスとの接続が確立されたときや切断されたときには通知を受けることができます。通知があり次第、{@link android.content.Context#bindService bindService()}
を呼び出して接続を設定します。
+{@link android.app.Service#onBind onBind()}
メソッドは、受け取ったインテント({@code bindService()} に渡されたインテント)に応じて、接続を承認または拒否するために実装します。接続が承認されると、接続を承認するのであれば、スタブ サブクラスのインスタンスを返します。
++ここでは、説明を簡単にするため、RPC メカニズムの細かい点は省略しています。詳しくは、Designing a Remote Interface Using AIDL、および {@link android.os.IBinder IBinder} クラスの説明をご覧ください。 +
+ + ++状況によっては実装したメソッドが複数のスレッドから呼び出されることもあるため、スレッドセーフな記述を心掛ける必要があります。 +
+ ++前のセクションで説明した RPC のようにメソッドをリモートで呼び出すことができる場合は、このような状況が特に発生しやすくなります。IBinder オブジェクトに実装されているメソッドを IBinder と同じプロセスから呼び出すと、そのメソッドは呼び出し側のスレッドで実行されます。一方、別のプロセスからメソッドを呼び出した場合は、プロセスのメイン スレッドではなく、IBinder と同じプロセス内に保持されているスレッドのプールから選択されたスレッドで実行されます。たとえば、サービスの {@code onBind()} メソッドはそのサービスのプロセスのメイン スレッドから呼び出されるのに対し、{@code onBind()} から返されたオブジェクトに実装されているメソッド(たとえば RPC メソッドを実装するスタブ サブクラス)はプール内のスレッドから呼び出されます。サービスには複数のクライアントを割り当てることができるため、複数のプール スレッドを同じ IBinder に同時に割り当てることも可能です。したがって、IBinder メソッドはスレッドセーフになるように実装する必要があります。 +
+ +
+同様に、コンテンツ プロバイダも別のプロセスからのデータ リクエストを受け取ることができます。ContentResolver および ContentProvider クラスはプロセス間通信の管理の詳細を隠蔽しますが、それらのリクエストに応答する ContentProvider メソッド({@link android.content.ContentProvider#query query()}
、{@link android.content.ContentProvider#insert insert()}
、{@link android.content.ContentProvider#delete delete()}
、{@link android.content.ContentProvider#update update()}
、および {@link android.content.ContentProvider#getType getType()}
メソッド)は、プロセスのメイン スレッドではなく、コンテンツ プロバイダのプロセス内のスレッドのプールから呼び出されます。これらのメソッドを同時に呼び出すことのできるメソッドの数に制限はありません。したがって、これらのメソッドもスレッドセーフになるように実装する必要があります。
+
+アプリケーション コンポーネントにはライフサイクルがあります。ライフサイクルは、インテントへ応答することでのインスタンス化で始まり、そのインスタンスの破棄で終わります。この間、コンポーネントがアクティブなときとアクティブでないときがあり、アクティビティであればユーザーから見えるときと見えないときがあります。このセクションでは、アクティビティ、サービス、およびブロードキャスト レシーバのライフサイクルについて説明します。具体的には、それぞれがライフタイムの間に取ることのできる状態、状態の遷移を通知する方法、およびそれらの状態が、コンポーネントを実行しているプロセスが終了させられたり、インスタンスが破棄されたりする可能性への影響などについて説明します。 +
+ + +アクティビティは、基本的に以下の 3 つの状態を取ります:
+ +状態が一時停止のアクティビティは、ユーザーのアクションの焦点から外れていますが、まだユーザーから見ることのできるアクティビティです。つまり、それよりも前面に他のアクティビティが表示されていますが、そのアクティビティが透明か全画面表示でないかのどちらかで、一時停止しているアクティビティの一部が見えている状態です。一時停止しているアクティビティは、完全に動作しています(すべての状態やメンバー情報は保持されており、ウィンドウ マネージャにアタッチされたままになっています)。ただし、メモリが極端に不足した場合は、システムによって強制終了させられる可能性があります。
状態が停止のアクティビティは、別のアクティビティに隠されて完全に見えなくなったアクティビティです。すべての状態とメンバー情報はまだ保持しています。しかし、もうユーザーに対して表示されていないため、他でメモリが必要な場合は強制終了させられる可能性が高いアクティビティです。
+システムが一時停止または停止しているアクティビティをメモリから削除する場合は、アクティビティの {@link android.app.Activity#finish finish()} メソッドを呼び出して終了を要求するか、単純のそのプロセスを強制終了します。そのアクティビティをもう一度ユーザーに表示する際は、完全に再起動して以前の状態に復元する必要があります。 +
+ ++アクティビティがある状態から別の状態に遷移すると、以下の protected メソッドに対する呼び出しによって変更が通知されます: +
+ +{@code void onCreate(Bundle savedInstanceState)}
{@code void onStart()}
{@code void onRestart()}
{@code void onResume()}
{@code void onPause()}
{@code void onStop()}
{@code void onDestroy()}
+これらのメソッドはすべて、状態が変化したときに適切な処理を行うためにオーバーライドできるフックです。オブジェクトが初めてインスタンス化されたときに初期設定を行うため、すべてのアクティビティには {@link android.app.Activity#onCreate onCreate()}
を実装する必要があります。多くのアクティビティには、データの変更をコミットするための {@link android.app.Activity#onPause onPause()}
も実装します。これを実装しない場合は、何らかの方法でユーザーとの対話を停止できるようにしておく必要があります。
+
+どのアクティビティ ライフサイクル メソッドの実装でも、必ず最初にスーパークラス バージョンを呼び出す必要があります。次に例を示します: +
+ +protected void onPause() { + super.onPause(); + . . . +}+
+これら 7 つのメソッドを使用すると、アクティビティのライフサイクル全体を定義できます。これらを実装することで、ネストされた 3 つのループからなるアクティビティのライフサイクルを監視できます: +
+ +{@link android.app.Activity#onCreate onCreate()}
が初めて呼び出されたときに始まり、最後に {@link android.app.Activity#onDestroy}
が呼び出されたときに終了します。アクティビティは、{@code onCreate()} で「全体的」な状態のすべての初期設定を行い、{@code onDestroy()} 残っていたリソースをすべて解放します。たとえば、ネットワークからのデータのダウンロードをバックグラウンドで実行するスレッドは、{@code onCreate()} で作成され、{@code onDestroy()} で停止します。アクティビティの可視ライフタイムは、{@link android.app.Activity#onStart onStart()}
の呼び出しで始まり、対応する {@link android.app.Activity#onStop onStop()}
の呼び出しで終了します。このライフタイムの間は、ユーザーが画面上でそのアクティビティを見ることができます。ただし、アクティビティがフォアグラウンドにない場合や、ユーザーと対話していない場合もあります。これらの 2 つのメソッドの間は、ユーザーに対してアクティビティを表示するために必要なリソースを確保できます。たとえば、{@code onStart()} で {@link android.content.BroadcastReceiver} を登録して UI に影響する変化を監視し、表示しているアクティビティがユーザーから見えなくなったら {@code onStop()} で登録を解除できます。{@code onStart()} および {@code onStop()} メソッドは、アクティビティがユーザーから見え隠れするたびに繰り返し呼び出すことができます。
アクティビティのフォアグラウンド ライフタイムは、{@link android.app.Activity#onResume onResume()}
の呼び出しで始まり、対応する {@link android.app.Activity#onPause onPause()}
の呼び出しで終了します。フォアグラウンド ランタイムの間は、このアクティビティが他のどのアクティビティよりも前面に表示され、ユーザーと対話しています。アクティビティは、一時停止状態と再開状態の間を頻繁に遷移します。たとえば、デバイスがスリープ状態になるときや新しいアクティビティを開始するときには {@code onPause()} が呼び出され、アクティビティの結果や新しいインテントが届いたときには {@code onResume()} が呼び出されます。したがって、これらのメソッドを記述する際は、できるだけ軽量化しておく必要があります。
+次の図に、これらのループとアクティビティの遷移経路を示します。色の付いた楕円は、アクティビティが取ることのできる主な状態です。長方形は、アクティビティが状態間を遷移するときに処理を実行するために実装できるコールバック メソッドを表します。 +
+ +
+ ++次の表では、各メソッドについて詳しく説明し、ライフサイクル全体における位置付けを示します: +
+ +メソッド | 説明 | 強制終了 | 次 | ||
---|---|---|---|---|---|
{@link android.app.Activity#onCreate onCreate()} |
+ アクティビティが初めて作成されるときに呼び出されます。通常の静的な設定(ビューの作成、リストへのデータのバインドなど)は、すべてのこのメソッドで行う必要があります。このアクティビティの 以前の状態が保存されていた場合、このメソッドにはその状態を保持している Bundle オブジェクトが引数として(詳しくは、後述のアクティビティの状態の保存をご覧ください)。
+ この後には、必ず {@code onStart()} が呼び出されます。 |
+ 不可 | +{@code onStart()} | +||
+ | {@link android.app.Activity#onRestart
+onRestart()} |
+ アクティビティが停止した後、それをもう一度開始する直前に呼び出されます。
+ この後には、必ず {@code onStart()} が呼び出されます。 |
+ 不可 | +{@code onStart()} | +|
{@link android.app.Activity#onStart onStart()} |
+ アクティビティがユーザーから見えるようになる直前に呼び出されます。
+ その後、アクティビティがフォアグラウンドに表示された場合は {@code onResume()} が、他のアクティビティの後ろに隠れた場合は {@code onStop()} が呼び出されます。 |
+ 不可 | +{@code onResume()} または {@code onStop()} |
+||
+ | {@link android.app.Activity#onResume onResume()} |
+ アクティビティがユーザーとの対話を開始する直前に呼び出されます。この時点で、アクティビティはアクティビティ スタックの最上位にあり、ユーザーからの入力はこのアクティビティに対して行われます。
+ この後には、必ず {@code onPause()} が呼び出されます。 |
+ 不可 | +{@code onPause()} | +|
{@link android.app.Activity#onPause onPause()} |
+ システムが別のアクティビティを開始しようとしているときに呼び出されます。このメソッドは、保存されていない変更を永続データにコミットする場合や、アニメーションのように CPU を大量に消費する処理を停止する場合に使用するのが一般的です。このメソッドが終了するまでは次のアクティビティが開始されたないため、できる限り短時間で実行できるようにしておく必要があります。
+ その後、アクティビティがフォアグラウンドに戻った場合は {@code onResume()} が、ユーザーから見えなくなった場合は {@code onStop()} が呼び出されます。 |
+ 可能 | +{@code onResume()} または {@code onStop()} |
+||
{@link android.app.Activity#onStop onStop()} |
+ アクティビティがユーザーから見えなくなったときに呼び出されます。見えなくなる状況としては、アクティビティが破棄された場合や、再開された別のアクティビティ(既存か新規かを問わず)によって隠された場合が考えられます。
+ その後、アクティビティがユーザーとの対話に戻った場合は {@code onRestart()} が、アクティビティが完全に終了する場合は {@code onDestroy()} が呼び出されます。 |
+ 可能 | +{@code onRestart()} または {@code onDestroy()} |
+||
{@link android.app.Activity#onDestroy
+onDestroy()} |
+ アクティビティが破棄される前に呼び出されます。これが、アクティビティが受け取る最後の呼び出しとなります。このメソッドが呼び出される状況としては、アクティビティが完了する場合({@link android.app.Activity#finish
+ finish()} が呼び出されたとき)や、システムが領域を確保するために一時的にそのアクティビティのインスタンスを破棄する場合が考えられます。これらの 2 つの状況は、{@link
+ android.app.Activity#isFinishing isFinishing()} メソッドを使用して識別できます。 |
+ 可能 | +なし | +
+表の強制終了列に注目してください。この列は、メソッドが終了した後であれば、システムがアクティビティのコードの別の行を実行することなくいつでもアクティビティを実行しているプロセスを強制終了できるかどうかを示しています。{@code onPause()}、{@code onStop()}、および {@code onDestroy()} メソッドの 3 つは「可能」となっています。1 番目に挙げた {@code onPause()} だけは、プロセスが強制終了する前に必ず呼び出されます。{@code onStop()} と {@code onDestroy()} は、必ず呼び出されるとは限りません。したがって、永続データ(たとえばユーザーによる編集)をストレージに書き込む際は {@code onPause()} を使用する必要があります。 +
+ ++強制終了列が「不可」になっているメソッドは、それらが呼び出された瞬間から、アクティビティを実行しているプロセスを保護して強制終了されないようにします。したがって、アクティビティが強制終了可能な状態にあるのは、たとえば {@code onPause()} が返されてから {@code onResume()} が呼び出されるまでの間ということです。その後は、もう一度 {@code onPause()} が返されるまで、強制終了できる状態には戻りません。 +
+ ++後述のプロセスとライフサイクルのセクションで詳しく説明しますが、ここでの定義で技術的には「強制終了可能」でないアクティビティでも、システムによって強制終了させられる可能性はありますが、他に利用できるリソースがないなど、極端に急を要する場合に限られます。 +
+ + ++メモリ不足を補うためにユーザーではなくシステムがアクティビティを終了させた場合には,ユーザがそのアクティビティに戻ったときに、以前の状態のままであることを期待するでしょう。 +
+ +
+アクティビティが強制終了させられる前の状態を保存しておきたい場合は、アクティビティに {@link android.app.Activity#onSaveInstanceState
+onSaveInstanceState()}
メソッドを実装します。このメソッドは、アクティビティが破棄されやすい状態になる前(つまり {@code onPause()} が呼び出される前)に呼び出されます。その際、アクティビティの動的な状態を名前/値ペアとして記録できる {@link android.os.Bundle} オブジェクトが渡されます。アクティビティがもう一度開始されると、Bundle は {@code onCreate()} だけでなく、{@code onStart()} の後に呼び出される {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}
メソッドにも渡され、保存されている状態をそのどちらかまたは両方で復元できます。
+
+{@code onSaveInstanceState()} および {@code onRestoreInstanceState()} メソッドは、これまでに説明した {@code onPause()} などとは異なり、ライフサイクル メソッドではありません。これらのメソッドは、常に呼び出されるわけではありません。たとえば、{@code onSaveInstanceState()} は、システムによってアクティビティが破棄しやすい状態にされる前には呼び出されますが、ユーザーのアクション(たとえば [[]戻る] キー)によってインスタンスが実際に破棄されるときには呼び出されません。そのような場合は、ユーザーがそのアクティビティに戻ることを想定する必要はないため、状態を保存する理由がないのです。 +
+ ++{@code onSaveInstanceState()} は常に呼び出されるとは限らないため、アクティビティの一時的な状態を記録する目的のみに使用し、永続データの格納には使用しないようにしてください。この目的には {@code onPause()} を使用します。 +
+ + ++あるアクティビティが別のアクティビティを開始すると、両方のアクティビティのライフサイクル状態が遷移します。一方が一時停止または停止し、もう一方が開始されます。場合によっては、これらの協調させる必要があります。 +
+ ++ライフサイクルのコールバックの順序は明確に定義されており、特に 2 つのアクティビティが同じプロセス内に存在する場合は次のようになります: +
+ ++サービスは、以下の 2 つの方法で使用できます: +
+ +{@link android.content.Context#startService Context.startService()}
が呼び出されて開始し、{@link android.content.Context#stopService Context.stopService()}
呼び出されて停止します。サービス自体が {@link android.app.Service#stopSelf() Service.stopSelf()}
または {@link android.app.Service#stopSelfResult Service.stopSelfResult()}
を呼び出して停止することもできます。サービスの開始時に {@code startService()} が何度呼び出されたとしても、{@code stopService()} を一度呼び出せばサービスは停止します。サービスで定義されているインターフェースをエクスポートし、これを介してプログラム的に操作できます。クライアントから Service オブジェクトへの接続を確立し、その接続を使用してサービスにアクセスします。接続は、{@link android.content.Context#bindService Context.bindService()}
を呼び出して確立し、{@link android.content.Context#unbindService Context.unbindService()}
でサービスを開始します。複数のクライアントが同じサービスにバインドすることも可能です。サービスがまだ開始されていなかった場合は,必要に応じて {@code bindService()} で開始できます。
+
+これら 2 つのモードは、完全に分離されているわけではありません。{@code startService()} で開始されたサービスにバインドすることも可能です。たとえば、再生する曲を指定した Intent オブジェクトで {@code startService()} を呼び出して音楽再生サービスを開始したとします。その後、たとえばユーザーがプレーヤーを操作したい場合や再生中の曲に関する情報を入手したい場合には、アクティビティから {@code bindService()} を呼び出してサービスとの接続を確立できます。このような場合、最後のバインドが閉じられるまでは、{@code stopService()} を呼び出してもサービスは停止しません。 +
+ ++アクティビティと同様、サービスにもライフサイクル メソッドがあり、これらを実装することでサービスの状態の変化を監視できます。ただし、protected ではなく public で、以下の 3 つしかありません: +
+ +{@code void onCreate()}
{@code void onStart(Intent intent)}
{@code void onDestroy()}
+これらのメソッドを実装することで、ネストされた 2 つのループからなるサービスのライフサイクルを監視できます: +
+ +{@link android.app.Service#onCreate onCreate()}
が呼び出されたときに始まり、{@link android.app.Service#onDestroy}
終了したときに終わります。アクティビティと同じく、サービスも {@code onCreate()} で初期設定を行い、{@code onDestroy()} で残っていたリソースをすべて解放します。たとえば、音楽再生サービスであれば、{@code onCreate()} で音楽を再生するスレッドを作成し、{@code onDestroy()} でそのスレッドを停止できます。サービスのアクティブ ライフタイムは、{@link android.app.Service#onStart onStart()}
を呼び出したときに始まります。このメソッドには、{@code startService()} に渡された Intent オブジェクトが渡されます。音楽再生サービスは、この Intent オブジェクトをみて曲を見つけ、その再生を開始します。
+サービスの停止に相当するコールバック、つまり {@code onStop()} メソッドはありません。 +
+{@code onCreate()} および {@code onDestroy()} メソッドは、サービスを {@link android.content.Context#startService Context.startService()}
または {@link android.content.Context#bindService Context.bindService()}
のどちらで開始したかに関係なく、すべてのサービスで呼び出されます。一方、{@code onStart()} は、サービスを {@code startService()} で開始した場合のみ呼び出されます。
+
+サービスが他からのバインドを許可している場合は、以下のコールバック メソッドを追加で実装できます: +
+ +{@code IBinder onBind(Intent intent)}
{@code boolean onUnbind(Intent intent)}
{@code void onRebind(Intent intent)}
+{@link android.app.Service#onBind onBind()}
コールバックには {@code bindService()} に渡された Intent オブジェクトが渡され、{@link android.app.Service#onUnbind onUnbind()}
には {@code unbindService()} 渡された Intent オブジェクトが渡されます。サービスがバインドを許可している場合は、クライアントがサービスと対話する通信チャネルを {@code onBind()} で返します。{@code onUnbind()} メソッドは、サービスに新しいクライアントが接続した場合に {@link android.app.Service#onRebind onRebind()}
の呼び出しを要求できます。
+
+次の図に、サービスのコールバック メソッドを示します。なお、{@code startService()} で作成されたサービスと、{@code bindService()} で作成されたサービスを分けて記述していますが、作成された方法に関係なく,すべてのサービスはクライアントからのバインドを許可できます。したがって、どのサービスも {@code onBind()} および{@code onUnbind()} メソッドの呼び出しを受け取る可能性はあります。 +
+ + + + ++ブロードキャスト レシーバのコールバック メソッドは次の 1 つのみです: +
+ +{@code void onReceive(Context curContext, Intent broadcastMsg)}
+ +
+レシーバにブロードキャスト メッセージが届くと、{@link android.content.BroadcastReceiver#onReceive onReceive()}
メソッドが呼び出され、メッセージを保持する Intent オブジェクトが渡されます。ブロードキャスト レシーバは、このメソッドの実行中のみアクティブと見なされます。{@code onReceive()} 終了すると、ブロードキャスト レシーバはアクティブでなくなります。
+
+ブロードキャスト レシーバがアクティブになっているプロセスは、強制終了しないよう保護されます。一方、アクティブでないコンポーネントのみからなるプロセスは、それが消費しているメモリが他のプロセスで必要になった場合は、いつでも強制終了される可能性があります。 +
+ ++この点は、ブロードキャスト メッセージへの応答に時間がかかるため、ユーザー インターフェースの他のコンポーネントを実行しているメイン スレッドとは別のスレッドで何らかの処理を行う必要がある場合に問題になります。{@code onReceive()} が新しいスレッドを生成して終了した場合、プロセス内に他にアクティブなアプリケーション コンポーネントがなければ、そのスレッドを含めたプロセス全体がアクティブでないと判断されて強制終了させられるおそれがあります。この問題を回避するには、{@code onReceive()} でサービスを開始し、そのサービスにジョブを実行させます。これにより、プロセス内にまだアクティブなコンポーネントがあると見なされます。 +
+ ++次のセクションでは、プロセスが強制終了される可能性が高くなる状況についてさらに詳しく説明します。 +
+ + +Android は、プロセスをできるだけ長い間維持しようとします。しかし、最終的にメモリが不足したときには、古いプロセスを削除しなければならなくなります。Android では、どのプロセスを維持し、どのプロセスを強制終了させるかを判断するため、プロセス内で実行されているコンポーネントと各コンポーネントの状態に基づいて、各プロセスを「重要度の階層」の位置づけます。まず最も重要度の低いプロセスが削除され、次は 2 番目に重要度の低いプロセス、その次に 3 番目、というように判断されます。階層は 5 つのレベルで構成されます。以下では、重要度の高いものから順に説明します: +
+ +{@link android.app.Activity#onResume
+onResume()}
メソッドが呼び出されている)。ユーザーと対話中のアクティビティにバインドされているサービスを実行している。
いずれかのライフサイクル コールバック({@link android.app.Service#onCreate
+onCreate()}
、{@link android.app.Service#onStart onStart()}
、または {@link android.app.Service#onDestroy onDestroy()}
)を実行している {@link android.app.Service} オブジェクトを保持している。
{@link android.content.BroadcastReceiver#onReceive
+onReceive()}
メソッドを実行している {@link android.content.BroadcastReceiver} オブジェクトを保持している。
+同時に存在するフォアグラウンド プロセスは少数に限られています。フォアグラウンド プロセスは、メモリが極端に不足し、すべてのフォアグラウンド プロセスの実行を継続できない場合の最終手段として強制終了させられます。通常、その時点でデバイスはメモリ ページングの状態に達しており、ユーザー インターフェースを応答可能な状態に維持するためには、フォアグラウンド プロセスの一部を強制終了させなければならない状況に陥っています。 +
可視プロセスは、フォアグラウンド コンポーネントではないものの、ユーザーが見ている画面に影響を及ぼすことのできるプロセスです。以下のいずれかの条件を満たしているプロセスは、可視プロセスと見なされます:
+ +{@link android.app.Activity#onPause onPause()}
メソッドが呼び出されている)。これは、たとえばフォアグラウンド アクティビティがダイアログで、その背後に直前のアクティビティが見えるような状況です。ユーザーから見ることのできるアクティビティにバインドされているサービスを実行している。
+可視プロセスは、非常に重要なプロセスと見なされ、すべてのフォアグラウンド プロセスの実行を維持するために必要でない限り、強制終了させられることはありません。 +
サービス プロセスは、{@link android.content.Context#startService startService()}
メソッドで開始されたサービスを実行しているプロセスのうち、より重要度の高い 2 つのレベルのどちらにも該当しないプロセスです。サービス プロセスは、ユーザーに見えるものとの直接的な関係はありませんが、たとえばバックグラウンドでの MP3 の再生、ネットワークからのデータのダウンロードなど、ユーザーが気にかけている処理であることが一般的です。したがって、すべてのフォアグラウンド プロセスと可視プロセスに加え、これらのサービス プロセスの実行を維持するだけのメモリが確保できる限り、強制終了させられることはありません。
+
バックグラウンド プロセスは、その時点でユーザーから見えないアクティビティを保持している(Activity オブジェクトの {@link android.app.Activity#onStop onStop()}
メソッドが呼び出されている)プロセスです。これらのプロセスは、ユーザー エクスペリエンスに直接的には影響しておらず、フォアグラウンド、可視、サービス プロセスからメモリが要求された場合はいつでも強制終了する可能性があります。通常は数多くのバックグラウンド プロセスが実行されているため、それらを LRU(least recently used)リストに登録し、ユーザーが一番最近見たアクティビティのプロセスが最後に強制終了するような仕組みになっています。アクティビティにライフサイクル メソッドが正しく実装されており、現在の状態が正しく保存されていれば、プロセスを強制終了してもユーザー エクスペリエンスに悪影響が及ぶことはありません。
+
空のプロセスは、アクティブなアプリケーション コンポーネントを保持していないプロセスです。このようなプロセスを維持しておく唯一の理由は、これをキャッシュとして使用し、次回コンポーネントを実行するときの起動時間を短くするためです。多くの場合、システムはこれらのプロセスを強制終了させて、プロセス キャッシュとその基礎となるカーネル キャッシュの間でシステム リソース全体のバランスを取ります。
+各プロセスは、その時点でアクティブなコンポーネントの重要度に基づいて、そのプロセスが取りうる最も高いレベルにランク付けされます。たとえば、あるプロセスがサービスと可視アクティビティをホストしている場合、そのプロセスはサービス プロセスではなく可視プロセスとしてランク付けされます。 +
+ ++また、あるプロセスに他のプロセスが依存しているために、そのプロセスのランクが引き上げられる可能性もあります。他のプロセスから依存されているプロセスが、依存しているプロセスよりも低いレベルにランク付けされることはありません。たとえば、プロセス A 内のコンテンツ プロバイダにプロセス B 内のクライアントが依存している場合や、プロセス A 内のサービスがプロセス B 内のコンポーネントにバインドされている場合、プロセス A は常にプロセス B よりは重要度が高いと見なされます。 +
+ ++サービスを実行しているプロセスは、バックグラウンド アクティビティを実行しているプロセスよりも高くランク付けされます。したがって、時間のかかる処理を実行する場合、特にその処理がアクティビティよりも長く続くような場合は、単にスレッドを生成するのではなく、その処理用のサービスを開始することをおすすめします。たとえば、バックグラウンドで音楽を再生する場合や、カメラで撮影した写真を Web サイトにアップロードする場合などはこれに当たります。サービスを使用することで、アクティビティがどのような状況にあっても、処理の重要度として「サービス プロセス」レベル以上を維持できます。ブロードキャスト レシーバのライフサイクルのセクションでも説明しましたが、ブロードキャスト レシーバにおいてもこれと同じ理由で、処理に時間がかかる場合はスレッドではなくサービスを使用することをおすすめします。 +
diff --git a/docs/html/intl/ja/guide/tutorials/hello-world.jd b/docs/html/intl/ja/guide/tutorials/hello-world.jd new file mode 100644 index 0000000..31857ce --- /dev/null +++ b/docs/html/intl/ja/guide/tutorials/hello-world.jd @@ -0,0 +1,375 @@ +page.title=Hello, World +@jd:body + +デベロッパーにとって、開発フレームワークの第一印象は、どれだけ簡単に「Hello, World」を記述できるかで決まります。Android では、非常に簡単に記述できます。総合開発環境として Eclipse を使用している場合には、開発は特に簡単です。プロジェクトの作成と管理に使用できる便利なプラグインが用意されており、開発サイクルを大幅にスピードアップできるためです。
+ +Eclipse を使用していない場合でも問題ありません。Developing in Other IDEsに慣れてから、このチュートリアルに戻り、Eclipse に関する部分以外を参考にしてください。
+ +開始する前に、最新の SDK がインストールされている必要があります。また、Eclipse を使用する場合には、ADT プラグインもインストールされている必要があります。これらのプログラムがインストールされていない場合は、「Installing the Android SDK」を参考にインストールを実行して、完了後にこのチュートリアルに戻ってください。
+ +AVD の使用方法と使用可能なオプションについて詳しくは、Android 仮想デバイス のドキュメントを参照してください。
+このチュートリアルでは、開発したアプリケーションを Android エミュレータで実行します。エミュレータを起動するには、事前に Android 仮想デバイス(AVD)を作成する必要があります。AVD は、エミュレータが使用するシステム イメージとデバイスの設定を定義するものです。
+ +AVD を作成するには、Android SDK に含まれている「android」ツールを使用します。コマンド プロンプトまたはターミナルを開き、SDK パッケージの中の tools/
ディレクトリに移動して、次のコマンドを実行します。
+
+android create avd --target 2 --name my_avd ++ +
カスタム ハードウェア プロファイルを作成するかどうかを尋ねられます。ここではひとまず、リターン キーを押してスキップします(デフォルトの回答は「No」となっています)以上で AVD の作成は終了です。この作業により、Android 1.5 プラットフォームを使用する「my_avd」という名前の AVD が構成されました。これで、AVD をエミュレータで使用できる状態になりました。
+ +上記のコマンドで使用した --target
オプションは、エミュレータを実行する配備ターゲットを指定するもので、必須オプションです。--name
オプションは新規 AVD の名前を定義するもので、これも必須オプションです。
AVD を作成したら、次は Eclipse 内で新規 Android プロジェクトを開始します。
+ +ADT Plugin for Eclipse が正常にインストールされていれば、表示されるダイアログに、「Android」というラベルの付いたフォルダと、その中の「Android プロジェクト(Android Project)」が表示されます(1 つまたは複数の Android プロジェクトを作成した後は、「Android XML File」というエントリも表示されるようになります)。
+[[]完了(Finish)] をクリックします。
+ + + +各フィールドの説明は以下のとおりです。
+ +パッケージ名は Android システムにインストールされたすべてのパッケージに共通して固有のものでなければなりません。このため、作成するアプリケーションに標準的なドメイン スタイルのパッケージを使用することが非常に重要です。上記の例では、「com.example」というネームスペースを使用しています。これはサンプル ドキュメント用のネームスペースです。実際にアプリケーションを作成する際には、所属する組織または法人に適切なネームスペースを使用します。
その他のフィールド: 「デフォルト ロケーションの使用」チェックボックスでは、プロジェクトのファイルが生成され保存されるディスク上の場所を変更することができます。「ビルド ターゲット」は、作成するアプリケーションがコンパイルされるときにターゲットとするプラットフォームです(この項目は [[]SDK の最小バージョン(Min SDK Version)] の入力値に基づいて自動的に選択されます)。
+ +ここで、選択した「ビルド ターゲット」で Android 1.1 プラットフォームが使用されることに注目してください。これは、作成するアプリケーションが Android 1.1 プラットフォーム ライブラリをターゲットとしてコンパイルされることを意味します。先ほど作成した AVD は Android 1.5 プラットフォームで実行されます。バージョンの数字が一致しませんが、Android アプリケーションには上方互換性があるため、1.1 プラットフォーム ライブラリをターゲットとして構築されたアプリケーションでも 1.5 プラットフォームで正常に動作します。ただしその逆の場合は正常に動作しません。
+さて、これで Android プロジェクトを使用できる状態になりました。プロジェクトは左側のパッケージ エクスプローラー(Package Explorer)で表示できます。「HelloAndroid」 > 「src」 > 「com.example.helloandroid」 の中にある HelloAndroid.java
ファイルを開きます。ファイルの内容は次のようになっています。
+package com.example.helloandroid; + +import android.app.Activity; +import android.os.Bundle; + +public class HelloAndroid extends Activity { + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + } +}+ +
クラスが {@link android.app.Activity} クラスに基づいていることに注目してください。アクティビティ(Activity)とは、処理を実行するために使用される単体のアプリケーション エンティティです。1 つのアプリケーションにはいくつものアクティビティが含まれる場合がありますが、ユーザーが一度に操作するのは 1 つのアクティビティです。アクティビティが開始すると、Android システムによって {@link android.app.Activity#onCreate(Bundle) onCreate()} メソッドが呼び出されます。このタイミングですべての初期化と UI セットアップを実行します。アクティビティにユーザー インターフェースは必須ではありませんが、通常はユーザー インターフェースを装備します。
+ +では、コードを変更してみましょう。
+ + +下記の変更済みのコードを参照して、お手元の HelloAndroid クラスに同じ変更を加えてみてください。太字の部分が追加された行です。
+ ++package com.android.helloandroid; + +import android.app.Activity; +import android.os.Bundle; +import android.widget.TextView; + +public class HelloAndroid extends Activity { + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + TextView tv = new TextView(this); + tv.setText("Hello, Android"); + setContentView(tv); + } +}+ +
ヒント: プロジェクトにインポート パッケージを簡単に追加できる方法として、Ctrl+Shift+O(Mac では コマンド+Shift+O)を押す方法があります。これは、コードの記述に基づいて足りないパッケージを特定して追加する Eclipse のショートカット キーです。
+ +Android のユーザー インターフェースは、「ビュー(Views)」と呼ばれるオブジェクトの階層で構成されています。{@link android.view.View} は、UI レイアウト内でボタン、画像、または(このサンプルのように)テキスト ラベルといった要素として使用される、描画可能なオブジェクトです。これらのオブジェクトのそれぞれが View クラスのサブクラスであり、テキストを処理するサブクラスは {@link android.widget.TextView} です。
+ +この変更では、クラス コンストラクタを使用して TextView を作成します。このクラス コンストラクタは、パラメータとして Android {@link android.content.Context} インスタンスを受け入れます。Context とは、システムへのハンドルであり、リソースの解決、データベースや設定へのアクセスの取得などのサービスを提供します。Activity クラスは Context を継承します。作成する HelloAndroid クラスは、Activity のサブクラスであるため、Context でもあります。したがって、this
を Context 参照として TextView に引き渡すことができます。
次に、{@link android.widget.TextView setText(CharSequence) setText()} を使用してテキスト コンテンツを定義します。
+ +最後に、そのコンテンツが Activity UI のコンテンツとして表示されるように、TextView を {@link android.app.Activity#setContentView(View) setContentView()} に引き渡します。Activity によってこのメソッドが呼び出されなければ、UI は表示されず、空白の画面が表示されます。
+ +これで、Android で「Hello, World」が表示されるようになりました。次の手順はもちろん、アプリケーションの実行です。
+ + +Eclipse プラグインでは、非常に簡単にアプリケーションを実行できます。
+ +Eclipse での起動構成の作成と編集について詳しくは、「ADT を使用した Eclipse での開発」を参照してください。
+Eclipse ADT によって自動的にプロジェクトの新規起動構成が作成され、Android エミュレータが自動的に起動します。エミュレータが起動した後、少し経つとアプリケーションが表示されます。次のような画面が表示されます。
+ + + +グレーのバーに表示されている「Hello, Android」は、アプリケーションのタイトルです。このタイトルは Eclipse プラグインによって自動的に作成されます(文字列は res/values/strings.xml
ファイル内で定義され、AndroidManifest.xml
によって参照されます)。タイトルの下のテキストは、先ほど TextView オブジェクトで作成した実際のテキストです。
これで「Hello World」についての基本的なチュートリアルは終了ですが、この続きもぜひ読んでください。Android アプリケーションの開発に関するさらに有益な情報を紹介しています。
+ + +先ほど作成した「Hello, World」のサンプルは、「プログラマティック」と呼ばれる UI レイアウトを使用しています。「プログラマティック」とは、アプリケーションの UI を直接ソース コードで作成および構築することを意味します。UI プログラミングの経験が豊富な方であればおそらく、このようなアプローチが時にいかに脆弱になり得るかをよくご存じでしょう。レイアウトの軽微な変更のたびに、ソース コード全体に関わる大きな問題が発生する可能性があるからです。また、複数のビューを適切に結びつけることも忘れられがちであるため、これによりレイアウトにエラーが発生し、コードのデバッグで時間が無駄になる場合があります。
+ +その理由から、Android では、XML ベースのレイアウト ファイルを使用する別の UI 構築モデルを用意しています。この概念を簡単に説明するには、サンプルを紹介するのが一番です。ここに示すのは、上記の「プログラマティック」に構築したサンプルと同じように動作する XML レイアウト ファイルです。
+ +<?xml version="1.0" encoding="utf-8"?> +<TextView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:text="@string/hello"/>+ +
Android XML レイアウト ファイルの全般的な構造はシンプルです。XML 要素がツリー構造になっており、含まれた各ノードが View クラスの名前を表しています(このサンプルでは View 要素が 1 つのみですが)。XML レイアウト内の要素として、{@link android.view.View} を拡張する任意のクラスの名前を使用できます。これには作成するコードの中で定義するカスタム View クラスも含まれます。この構造により、プログラマティックなレイアウトよりもシンプルな構造と構文を使用して、迅速な UI 構築を非常に簡単に行うことができます。このモデルは、アプリケーションの表示(つまり UI)を、データの取得と入力に使用されるアプリケーション ロジックから切り離すことができる Web 開発モデルからヒントを得て考案されました。
+ +上記の XML サンプルには、TextView
という View 要素 1 つのみが含まれています。この要素は 4 つの XML 属性を持っています。下表に、これらの 4 つの属性の説明をまとめました。
+ 属性 + | ++ 説明 + | +
---|---|
+ xmlns:android
+ |
+
+ Android ネームスペースで定義された共通の属性を参照することを Android ツールに伝える XML ネームスペース宣言です。すべての Android レイアウト ファイル内の最初と最後のタグはこの属性を持つ必要があります。 + |
+
+ android:layout_width
+ |
+
+ 該当の View が画面の利用可能な幅のうちどれくらいを占めるかを定義します。このサンプルでは、この View しかないため、「fill_parent」という値を使用して画面全体を占めることにします。 + |
+
+ android:layout_height
+ |
+ + android:layout_width とよく似た属性で、幅ではなく高さを表します。 + | +
+ android:text
+ |
+ + TextView が表示するテキストを設定します。このサンプルでは、ハードコード記述された文字列値ではなく文字列リソースを使用します。文字列「hello」は res/values/strings.xml ファイル内で定義されます。アプリケーションに文字列を挿入する場合にはこの方法が推奨されます。レイアウト ファイルのハードコードを直接変更する必要がないため、アプリケーションの他の言語へのローカライズがスムーズに進むからです。詳しくは、「リソースと国際化」を参照してください。 + | +
これらの XML レイアウト ファイルは、作成するプロジェクトの res/layout/
ディレクトリ内に置かれます。「res」は「resources」の略で、アプリケーションに必要なコード以外のすべてのアセットがこのディレクトリに格納されます。リソースには、レイアウト ファイルの他に、画像、音声、ローカライズされた文字列などのアセットがあります。
横表示の場合に異なるデザインで表示するには、レイアウト XML ファイルを /res/layout-land 内に入れます。Android 端末のレイアウトが横表示に変わると自動的にこのディレクトリが参照されます。このように横表示向けに定義されたレイアウトが存在しない場合、自動的にデフォルトのレイアウトが拡大して使用されます。
+Eclipse プラグインでは、このようなレイアウト ファイルの 1 つである「main.xml」が自動的に作成されます。先ほど「Hello World」アプリケーションを作成した際には、このファイルは無視してプログラマティックにレイアウトを作成しました。この作成方法は Android フレームワークについてより深く理解していただくことを意図したもので、実際にはほとんどの場合レイアウトはコードではなく XML ファイルで定義します。以下の手順では、既存のアプリケーションを変更して XML レイアウトが使用されるようにする方法を説明します。
+ +/res/layout/
フォルダを展開し、main.xml
を開きます(開いた後、場合によっては XML ソースを見るのにウィンドウ下部にある「main.xml」タブをクリックする必要があります)。ファイルの内容を以下の XML に置き換えます。
+
+<?xml version="1.0" encoding="utf-8"?> +<TextView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:text="@string/hello"/>+
ファイルを保存します。
+res/values/
フォルダ内の strings.xml
を開きます。このファイルは、作成するユーザー インターフェースのためのすべてのデフォルトのテキスト文字列を保存するものです。Eclipse を使用している場合、ADT によってあらかじめ hello と app_name という 2 つの文字列が用意された状態になります。hello を何か別の文字列に書き換えてみましょう。たとえば「Hello, Android! I am a string resource!」としてみましょう。変更後のファイルの全体は次のようになります。
++<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="hello">Hello, Android! I am a string resource!</string> + <string name="app_name">Hello, Android</string> +</resources> ++
HelloAndroid
クラスを開いて、XML レイアウトを使用して変更します。ファイルを編集して次のような内容にします。
++package com.example.helloandroid; + +import android.app.Activity; +import android.os.Bundle; + +public class HelloAndroid extends Activity { + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.main); + } +}+ +
この変更を行う際に、コードを手入力してコード補完機能を試してみましょう。「R.layout.main」と入力しようとすると、プラグインによって入力候補が表示されます。この機能の便利さは、開発中に何回も実感すると思います。
+ +View オブジェクトに setContentView()
を引き渡す代わりに、レイアウト リソースへの参照を付与します。リソースは R.layout.main
として識別されます。これは、/res/layout/main.xml
で定義されたレイアウトを、コンパイルされたオブジェクトで表したものです。Eclipse プラグインでは、この参照がプロジェクトの R.java クラス内に自動的に作成されます。Eclipse を使用していない場合、Ant を実行してアプリケーションのビルドを行う際に R.java クラスが生成されます(R クラスについて詳しくは後ほど説明します)。
ここで、アプリケーションを再実行します。起動構成は作成済みであるため、ここでは緑色の矢印アイコンをクリックして実行するか、または [[]実行(Run)] > [[]ヒストリーの実行(Run History)] > [[]Android Activity] を選択するだけです。TextView 文字列に加えた変更を除けば、アプリケーションは同じに見えます。ここでポイントとなるのは、2 つの異なるレイアウト編集方法を使用して同じ結果が得られるということです。
+ +ヒント: ショートカット キーCtrl+F11(Mac では コマンド+Shift+F11)を使用して、現在表示されているアプリケーションを実行することができます。
+ +ここからは、デバッグの基礎知識と、他の総合開発環境に関する補足情報について説明します。さらに詳しく学習したい場合は、「アプリケーションの基礎」を参照してください。Android アプリケーションが動作するためのすべての要素について説明しています。また、「デベロッパー ガイド」の導入ページを参照して、デベロッパー ガイド ドキュメントの概要を確認してください。
+ + +Eclipse で、R.java
という名前のファイル(gen/
(「生成された Java ファイル(Generated Java Files)」フォルダ内)を開きます。ファイルの内容は次のようになっています。
+package com.example.helloandroid; + +public final class R { + public static final class attr { + } + public static final class drawable { + public static final int icon=0x7f020000; + } + public static final class layout { + public static final int main=0x7f030000; + } + public static final class string { + public static final int app_name=0x7f040001; + public static final int hello=0x7f040000; + } +} ++ +
プロジェクトの R.java
ファイルは、ファイル内で定義されたすべてのリソースへのインデックスです。ソース コード内では、プロジェクトに含めたすべてのリソースを参照するための簡略形式としてこのクラスを使用します。これは、Eclipse などの総合開発環境のコード補完機能とともに使用すると特に便利です。探している特定の参照をすばやくインタラクティブに見つけることができるからです。
お手元のファイルはこれとは若干異なる可能性があります(おそらく 16 進値が異なるためです)。ここでは、「layout」という名前の内部クラスと、そのメンバーであるフィールド「main」に注目します。Eclipse プラグインにより main.xml という名前の XML レイアウト ファイルが認識され、ここにそのためのクラスが生成されたものです。プロジェクトに他のリソース(res/values/string.xml
ファイル内の文字列や res/drawable/
ディレクトリ内の描画可能オブジェクトなど)を追加すると、R.java
に最新の変更が反映されます。
Eclipse を使用していない場合は、(Ant ツールを使用した)ビルド時にこのクラス ファイルが生成されます。
+くれぐれもこのファイルを手動で編集しないようにしてください。
+Android Plugin for Eclipse は、Eclipse のデバッガと優れた連動性を発揮します。このメリットを確認するため、作成したコードにバグを埋め込んでみましょう。作成した HelloAndroid ソース コードを次のように変更します。
+ ++package com.android.helloandroid; + +import android.app.Activity; +import android.os.Bundle; + +public class HelloAndroid extends Activity { + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Object o = null; + o.toString(); + setContentView(R.layout.main); + } +}+ +
この変更は、単にコードに NullPointerException を発生させるものです。アプリケーションを再度実行すると、最終的に次のような画面が表示されます。
+ + + +「強制終了」を押してアプリケーションを終了し、エミュレータ ウィンドウを閉じます。
+ +エラーの詳細を確認するには、ソース コード内の Object o = null;
行にブレークポイントを設定します(該当するソース コード行の横にあるマーカー バーをダブルクリックします)。次に、メニューから [[]実行(Run)] > [[]デバッグ ヒストリー(Debug History)] > [[]Hello, Android] を選択して、デバッグ モードに入ります。エミュレータでアプリケーションが再起動されますが、今度は、先ほど設定したブレークポイントに到達した時点で中断されます。その後 Eclipse のデバッグ パースペクティブ(Debug Perspective)で、他のアプリケーションで通常行うように、コードの内容を確認できます。
Eclipse を使用していない場合(普段から使用している総合開発環境がある場合や、シンプルにテキスト エディタやコマンド ライン ツールを使用している場合など)は、Eclipse プラグインを利用することはできません。しかし心配は無用です。Eclipse を使用していないからといって何らかの機能が失われることはありません。
+ +Android Plugin for Eclipse は、単に Android SDK に含まれるツール セットをまとめたものに過ぎません(エミュレータ、aapt、adb、ddms などの個別のツールについては、こちらで別途説明しています)。このため、これらのツールを別のツール、たとえば「Ant」のビルド ファイルなどでまとめることも可能です。
+ +Android SDK には、「android」という名前のツールが含まれています。このツールを使用すると、作成するプロジェクトのソース コードとディレクトリ スタブすべて、および Ant と互換性のある build.xml
ファイルを作成することができます。これにより、プロジェクトをコマンド ラインで作成したり、普段使用している総合開発環境と統合したりすることができます。
たとえば、Eclipse で作成されるものと同様の HelloAndroid プロジェクトを作成するには、次のコマンドを使用します。
+ ++android create project \ + --package com.android.helloandroid \ + --activity HelloAndroid \ + --target 2 \ + --path <path-to-your-project>/HelloAndroid ++ +
これにより、path で定義された場所に、プロジェクトに必要なフォルダとファイルが作成されます。
+ +SDK ツールを使用してプロジェクトを作成および構築する方法について詳しくは、「Developing in Other IDEs」を参照してください。
-- cgit v1.1