Androidアプリケーション技術者認定試験ベーシックの試験範囲の知識をまとめた(6)

# アプリケーションコンポーネント

## アプリケーションコンポーネントの概要

### アプリケーションコンポーネントとは

特定の役割を持ち、部品として利用可能なもの。

#### アクティビティ（概要）

ユーザーインターフェースを持つコンポーネント。ボタンやメニューなどのビューを表示する。
android.app.Activityクラスを継承して作成する

#### コンテントプロバイダ（概要）

アプリケーション間でデータ共有を行うためのコンポーネント。連絡先、写真、設定情報などを提供。
android.content.ContentProviderを継承する独自のコンテントプロバイダを作ることも可能

#### サービス（概要）

バックグラウンドで非同期に処理を行うもの
android.app.Serviceクラスを継承して作成する。

#### ブロードキャストレシーバ（概要）

システムからのメッセージを非同期に受信するためのもの
Androidアプリケーションが送信するメッセージの受信にも使用可能。
adndroid.content.BroadcastReceiverクラスを継承して作成する

### Androidアプリケーションへの登録

独自に作成したアプリケーションコンポーネントはマニフェストファイルに登録する必要がある
`<application>`タグは以下に次のタグでコンポーネント名などを設定する。

|||
|---|---|
|アクティビティ|`<activity>`タグ|
|コンテントプロバイダ|`<provider>`タグ|
|サービス|`<service>`タグ|
|ブロードキャストレシーバ|`<receiver>`タグ|

### インテントによる起動

アクティビティ、サービス、ブロードキャストレシーバは、インテントによって起動する。
intentオブジェクトを生成して、起動する。
明示的インテントと暗黙的インテントの2種類がある。

## アクティビティ

### アクティビティとは

ユーザーインターフェースを持つ、アプリケーションコンポーネント。
onCreateはアクティビティのライフサイクルメソッドの一つでアクティビティの起動の際に呼び出される。
setContentViewはアクティビティにビューを設定するメソッド。

ユーザーインターフェースを持つアプリケーションは必ずアクティビティを持つ。

### アクティビティのライフサイクル

アクティビティはライフサイクルを持つコンポーネント。遷移するたびにライフサイクルメソッドが呼び出される

#### アクティビティの状態

- アクティブ状態　画面のフォアグラウンドに表示されていて、操作対象となる状態。
- 一時停止状態 表示されていない（別のアクティビティが表示されている）状態。
- 停止状態 表示されていない（別のアクティビティが表示されている)状態。メモリ不足の際には、強制的に終了させられる可能性がある。

#### アクティビティのライフサイクルメソッド

![ライフサイクルメソッド](https://developer.android.com/images/activity_lifecycle.png?hl=ja)
https://developer.android.com/guide/components/activities.html?hl=ja

アクティビティのライフサイクルメソッド

|||
|---|---|
|onCreate|最初に起動するとき|onStart|
|onStart|ユーザに表示される直前|onResumeまたはonStop|
|onResume|ユーザーとのやり取りが可能になる直前|onPause|
|onPause|フォアグラウンドから消える直前|onResumeまたはonStop|
|onStop|表示されなくなった時（別アクティビティに隠されるか、終了または破棄されるとき）|onRestartまたはonDestory|
|onRestart|非表示状態のアクティビティが、再度フォアグラウンドに表示されるとき|onStart|
|onDestroy|破棄される前に呼び出される|なし|

各ライフサイクルメソッドは必要に応じてオーバーライドして利用する。

##### システムによる強制終了

onPauseの後にonStopやonDestroyが呼び出されない場合もある。（メモリ不足などによる強制終了)
データの保存などはonPauseメソッドで行う必要がある。

#### アクティビティのライフタイム

アクティビティには3つのライフタイムがある

- ライフタイム全体 onCreateの呼び出しで始まりonDestoryの呼び出しで終わる
- 可視ライフタイム onStartの呼び出しで始まりonStopの呼び出しで終わる
- フォアグラウンドライフタイム onResumeの呼び出しで始まりonPauseの呼び出しで終わる

### アクティビティの起動と終了

#### アクティビティの起動

アクティビティから別のアクティビティを移動するにはContextクラスのstartActivityメソッドを使う。
引数にはIntentオブジェクトを指定する。

別のアクティビティを起動して、処理の結果を受け取りたい場合はstartActivityForResultを使う。
引数にはIntentオブジェクトと要求コードを指定する。

startActivityForResultで起動した処理の結果を受け取るには起動元のアクティビティでonActivityResultメソッドをオーバライドして使う
第一引数は要求コード、第二引数が結果コード、第三引数がインテントオブジェクト(呼び出し先でsetResultされたもの)

#### アクティビティの終了

自分自身を終了する場合、finishメソッドを使う。
呼び出し先を終了する場合、finishActivityメソッドを使う。引数はstartActivityForResult時に指定した要求コードを指定する。

##### Androidアプリケーションのプロセス

プロセスは5種類あり、メモリ不足の場合など優先度の低いプロセスから終了することがある。

プロセスの種類

|||
|---|---|
|フォアグラウンドプロセス|ユーザーが使用中のアクティビティ|
|可視プロセス|ユーザーに表示されているアクティビティ|
|サービスプロセス|上2種以外のうちstartServiceで起動されたサービスを実施中のプロセス|
|バックグラウンドプロセス|ユーザーに見えていなくて、onStopが呼び出されているアクティビティのあるプロセス|
|空のプロセス|処理を実行中のコンポーネントが存在しないプロセス|

## インテントとインテントフィルタ

### インテントとは

アクティビティ、サービス、ブロードキャストレシーバを起動するための非同期メッセージ

インテントに指定することのできる情報

|||
|---|---|
|コンポーネント|インテントを受信するコンポーネント|
|アクション|コンポーネントが実行する動作、または発生したイベントを表す文字列|
|データ|コンポーネントが処理するデータのURLとMIME型|
|カテゴリ|インテントを受信するコンポーネントの種類|
|拡張情報|インテントを受信するコンポーネントに渡す追加情報|
|フラグ|コンポーネントの起動方法などを示すフラグ|

### インテントの利用方法

#### インテントの生成

起動する場合に使用するメソッド

|||
|---|---|
|アクティビティ|ContextクラスのstartActivityメソッド、ActivityクラスのstartActivityForResultメソッド|
|サービス|ContextクラスのstartServiceメソッド、bindServieメソッド|
|ブロードキャストレシーバ|ContextクラスのsendBroadcastメソッド、sendOrderedBroadcastメソッド、sendStickyBroadcastメソッド|

Intentオブジェクトを生成するための引数は、アクション、データのURI、コンテキスト、起動するコンポーネントのクラスを指定する。

生成したインテントに対する情報設定メソッド

|||
|---|---|
|setClass|インテントを受信するコンポーネントのクラス|
|setClassName|インテントを受信するコンポーネントのクラス名|
|setDataAndType|処理するデータのURIとMIME型|
|setData|処理するデータのURI|
|setType|処理するデータのMIME型|
|setFlags|フラグ|
|pubExtra|追加情報|

#### インテントの取得

起動先のアクティビティではgetIntentメソッドで使われたIntentオブジェクトを取得可能。

|||
|---|---|
|getAction|アクション|
|getCompornent|起動したコンポーネントに関する情報|
|getData|処理するデータのURI|
|getType|処理するデータのMIME型|
|getFlags|フラグ|
|getXxxExtra|追加情報(Xxxはデータ型)|

##### コンポーネントのクラス名

getComportnentメソッドはComponentNameオブジェクトを返す。ComponentNameオブジェクトに対してgetClassNameメソッドを呼び出すとコンポーネントのクラス名を取得できる。

### 明示的インテントと暗黙的インテント

#### 明示的インテントとは

Intentオブジェクトに対して、起動先を指定して生成したものを明示的インテントという

#### 暗黙的インテントとは

Intentオブジェクトに対して、起動先を指定せず生成したものを暗黙的インテントという
他のアプリケーションに含まれるコンポーネントなどは起動先のクラスが不明なため、アクションを指定する。

### 暗黙的インテントとインテントフィルタ

#### インテントフィルタとは

暗黙的インテントで起動された場合は、クラス名の指定がないため、どれを起動するかを判定しないといけない。
その判定のために使うのがインテントフィルタ。
IntentFilterオブジェクトはマニフェストファイルの`<activity>`タグ、`<service>`タグ、`<receiver>`タグの配下に`<intent-filter>`タグで定義する。

`<intent-filter>`タグの子タグには`<action>`,`<category>`,`<data>`,などのタグが指定出来る。

#### アクション

アクションは、コンポーネントが実行すべき操作や、システムで発生したイベントを表す。

アクティビティ用の主なアクション

|||
|---|---|
|ACTION_DELETE|データの削除|
|ACTION_EDIT|データの編集|
|ACTION_INSERT|データの挿入|
|ACTION_PICK|データの選択|
|ACTION_RUN|データの実行|
|ACTION_SYNC|データの同期|
|ACTION_SEARCH|データの検索|
|ACTION_SEND|データの送信|
|ACTION_SEND_MULTIPLE|複数のデータの送信|
|ACTION_VIEW|データの表示|
|ACTION_ANSWER|かかってきた電話を受ける|
|ACTION_CALL|指定された番号に電話をかける|
|ACTION_DIAL|指定された番号をダイヤルする|
|ACTION_ALL_APPS|アプリケーションの一覧表示|
|ACTION_INSTALL_PACKAGE|パッケージのインストール|
|ACTION_UNINSTALL_PACKAGE|パッケージのアンインストール|
|ACTION_MAN|アプリケーションのエントリポイントとして実行|

ブロードキャストレシーバ用の主なアクション]

|||
|---|---|
|ACTION_PACKAGE_CHANGED|パッケージの変更|
|ACTION_PACKAGE_FULLY_REMOVED|パッケージの削除|
|ACTION_BATTERY_LOW|バッテリ残量の低下|
|ACTION_BATTERY_OKAY|バッテリ残量OK|
|ACTION_SCREEN_OFF|画面のオフ|
|ACTION_SCREEN_ON|画面のオン|
|ACTION_SHUTDOWN|デバイスのシャットダウン|
|ACTION_BOOT_COMPLETED|システムのブート|
|ACTION_REBOOT|デバイスの再起動|
|ACTION_CONFIGURATION_CHANGED|設定の変更|
|ACTION_LOCALE_CHANGED|ロケールの変更|
|ACTION_TIME_TICK|現在時刻の変更|
|ACTION_DATE_CHANGED|日付の設定|
|ACTION_TIME_CHANGED|時刻の設定|
|ACTION_TIMEZONE_CHANGED|タイムゾーンの設定|

独自にアクションを指定することも可能

## コンテントプロバイダ

### コンテントプロバイダとは

異なるアプリケーション間でのデータ共有を可能にするのが、コンテントプロバイダ。

- システムや、他のアプリケーションのコンテントプロバイダからデータを取得する
- 独自にコンテントプロバイダを作成して他のアプリケーションにデータを提供する

### コンテントプロバイダを使ったデータの取得

ContentResolverオブジェクトを使用する。
ContentResolverオブジェクトで検索し、戻ってきたCursorオブジェクトからデータを取得する

#### ContentResolverオブジェクトの取得

ContextクラスのgetContentResolverメソッドで取得する。

#### データの検索

queryメソッドを使ってデータを検索する

第一引数 コンテントプロバイダのURI
第二引数 取得する列名（すべての場合はNULL)
第三引数 データ取得の条件を表す文字列（すべての場合はNULL)
第四引数 第三引数の中で?と置き換える文字列
第五引数 行の並べ替えの条件（ASC、DESC）

#### Cursorオブジェクトからのデータの取得

CursorにはContentResolverのqueryメソッドで取得したデータを保持する

1. CursorのgetColumnIndexを呼び出し取り出したい列のインデックスを取得
1. CursorのmoveToFirstを呼び出し、Cursorオブジェクトの現在位置を先頭に移動
1. 取得したインデックスを指定してgetXxx(Xxxはデータ型)で列のデータを取り出す
1. moveToNextメソッドで次の行に移動
1. 上を繰り返し、moveToNextメソッドがfalseを返した場合に終了する

##### パーミッションについて

電話番号を取得する場合、`<uses-permission>`でREAD_CONTACTSを設定する必要がある。

### コンテントプロバイダの作成

他のアプリケーションにデータを公開するため。独自にコンテントプロバイダを作成するには、
android.content.ContentProviderクラスを継承するクラスを作成する。
作成したコンテントプロバイダはマニフェストファイルに`<provider>`タグで定義する。

継承する際実装する必要があるメソッド

|||
|---|---|
|onCreate|初期化処理|
|delete|データの削除|
|insert|データの挿入|
|update|データの更新|
|getType|MIME型の取得|
|query|データの検索|

## サービス

### サービスとは

バックグラウンド処理を行うアプリケーションコンポーネント

### サービスのライフサイクル

サービスもアクティビティと同様にライフサイクルを持つ。
起動のされ方で、ライフサイクルメソッドが異なることに注意。

![サービスのライフサイクルメソッド](https://developer.android.com/images/service_lifecycle.png?hl=ja)

https://developer.android.com/guide/components/services.html?hl=ja

サービスのライフサイクルメソッド

|||
|---|---|
|onCreate|サービスが生成されるときに呼び出される（生成済みの場合は呼び出されない）|
|onStartCommand|サービスがstartServiceメソッドで起動された場合呼び出される|
|onBind|サービスがbindServiceメソッドで起動されたときに呼び出される|
|onDestory|サービスがstopServiceまたはstopSelfメソッドで終了した時、またはonUnbindメソッドが呼び出されたあとに呼び出される|
|onUnbind|サービスがunbindServiceメソッドでバインド解除されたときに呼び出される|

### サービスの起動と終了

#### サービスの起動

2種類の方法で起動できる。

ContextクラスのstartServiceメソッドを使う方法は、起動するサービスに関するIntentオブジェクトを指定する。
ContextクラスのbindServiceメソッドを使って、生成済みのっサービスにバインドする方法は、
第一引数にはサービスの情報を設定したインテント、第二引数にはサービスの生成や、起動に関する情報を受け取るためのServiceConnectionオブジェクト、第三引数にはバインド方法を指示するフラグをContextクラスの定数で指定する。

#### サービスの終了

3種類の方法で終了できる。

実行中のサービスはstopSelfメソッドで自分自身を終了できる

startServiceで起動したサービスは、ContextクラスのstopServiceメソッドで終了できる。

bindServiceでバインドしたサービスは、ContextクラスのunbindServiceメソッドで終了できる。
引数にはbindServiceに渡したのと同じServiceConnectionオブジェクトを指定する。

##### サービスのバインド解除と終了

unbindServiceを呼び出しても他にそのサービスにバインドしているアクティビティが存在する場合は、
すぐには終了しない。すべてのバインドが解除されると終了する。

## ブロードキャストレシーバ

### ブロードキャストレシーバの使い方

Androidではイベントが発生すると、インテントがブロードキャストされる。
ブロードキャストレシーバは非同期に発生するイベントを受信するためのコンポーネント。
アクティビティやサービスで受信することも可能

#### ブロードキャストレシーバのライフサイクル

ライフサイクルメソッドとしてはonReceiveのみを持つ。

#### ブロードキャストレシーバによるインテントの受信

独自のレシーバを作るには、android.content.BroadcastReceiverクラスを継承する。
マニフェストファイルの`<application>`タグの配下に`<receiver>`タグで定義する。
`<receiver>`タグの配下の`<intent-filter>`タグと`<action>`タグで受信可能なアクションを指定する。

##### ブロードキャストレシーバの登録

マニフェストファイルに定義するだけでなく、プログラム中に動的に登録可能である。
ContextクラスのregisterReceiverメソッドを使って行う。

#### ブロードキャストレシーバへのインテントの送信

アクティビティやサービスからブロードキャストレシーバにインテントを送信するには、ContextクラスのsendBroadcastメソッドを使う。

##### インテントを送信するその他のメソッド

他にもsendOrdereBroadcastメソッド、sendStickyBroadcastメソッド、sendStickyOrderedBroadcastメソッドが用意されている。