Androidアプリでアクティビティ間でデータをやり取りする方法 (日本語)
Androidアプリにおいて、アクティビティ間でデータをやり取りする方法はいくつかあります。ここでは、そのうち2つの主要な方法について説明します。
Intentを使用する
Intentは、アプリケーション内のコンポーネント間でメッセージやデータを伝達するためのオブジェクトです。アクティビティ間でデータをやり取りする最も一般的な方法です。
方法:
データの格納:
Intent
オブジェクトを作成します。putExtra()
メソッドを使用して、キーと値のペアでデータを格納します。さまざまなデータ型(String、int、boolean、Serializable、Parcelableなど)を格納できます。
val intent = Intent(this, SecondActivity::class.java) intent.putExtra("name", "John") intent.putExtra("age", 30)
アクティビティの起動:
startActivity(intent)
- 次のアクティビティでは、
getIntent()
メソッドを使用してIntentを取得し、getStringExtra()
などのメソッドを使用してデータを取り出します。
val name = intent.getStringExtra("name") val age = intent.getIntExtra("age", 0)
- 次のアクティビティでは、
Bundleを使用する
Bundleの作成:
Bundle
オブジェクトを作成し、putString()
、putInt()
などのメソッドを使用してデータを格納します。
val bundle = Bundle() bundle.putString("name", "John") bundle.putInt("age", 30)
Intentへの追加:
Intent
オブジェクトのputExtras()
メソッドを使用して、Bundleを格納します。
val intent = Intent(this, SecondActivity::class.java) intent.putExtras(bundle)
val bundle = intent.extras val name = bundle?.getString("name") val age = bundle?.getInt("age")
注意:
- SerializableまたはParcelableインターフェースを実装したカスタムオブジェクトをIntentに渡す場合は、これらのオブジェクトもシリアライズまたはパーセル化できる必要があります。
startActivityForResult()
メソッドを使用すると、次のアクティビティから結果を返すことができます。- アクティビティ間のデータのやり取りには、これらの方法以外にも、サービスや BroadcastReceiver を使用する方法もあります。
Android アクティビティ間データやり取りのコード例詳細解説
Intent を使ったデータの受け渡し
// MainActivity (データを送信するアクティビティ)
val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("name", "太郎")
intent.putExtra("age", 20)
startActivity(intent)
- Intentの作成:
Intent
オブジェクトを生成し、遷移先のSecondActivity
クラスを指定します。 - データの格納:
putExtra()
メソッドを使って、キーと値のペアでデータを格納します。ここでは、"name"というキーに"太郎"、"age"というキーに20という整数を格納しています。 - アクティビティの起動:
startActivity()
メソッドでSecondActivity
を起動し、作成したIntent
を渡します。
// SecondActivity (データを受信するアクティビティ)
val name = intent.getStringExtra("name")
val age = intent.getIntExtra("age", 0)
textView.text = "名前: $name, 年齢: $age"
- Intentの取得:
getIntent()
メソッドで、MainActivity
から渡されたIntent
を取得します。 - データの取得:
getStringExtra()
やgetIntExtra()
メソッドを使って、キーに対応する値を取り出します。getIntExtra()
の第2引数は、値が見つからなかった場合のデフォルト値です。 - データの表示: 取得したデータを
TextView
に表示します。
Bundle を使ったデータの受け渡し
// MainActivity
val bundle = Bundle()
bundle.putString("name", "次郎")
bundle.putInt("age", 30)
val intent = Intent(this, SecondActivity::class.java)
intent.putExtras(bundle)
startActivity(intent)
- Intentへの追加:
putExtras()
メソッドで、作成したBundle
をIntent
に格納します。
// SecondActivity
val bundle = intent.extras
val name = bundle?.getString("name")
val age = bundle?.getInt("age")
textView.text = "名前: $name, 年齢: $age"
- Bundleの取得:
getExtras()
メソッドで、Intent
からBundle
を取得します。 - データの取得:
getString()
やgetInt()
メソッドを使って、キーに対応する値を取り出します。
どちらを使うべきか?
- シンプルなデータの受け渡し:
Intent
のputExtra()
メソッドで直接データを格納する方が簡単です。 - 複雑なオブジェクトの受け渡し:
Serializable
やParcelable
インターフェースを実装したカスタムオブジェクトをIntent
に渡す場合は、Bundle
を使う方が便利です。
- サービスやBroadcastReceiverを使って、アクティビティ間でデータをやり取りすることも可能です。
- 上記のコードはKotlinで記述されています。Javaでも同様のことができます。
- データの種類によって、適切なデータ型を使って
putExtra()
やputExtras()
メソッドに渡す必要があります。 Serializable
やParcelable
インターフェースについては、より複雑なオブジェクトをIntentに渡す際に必要となるため、別途学習する必要があります。
より詳細な解説:
- Intentの仕組み: Intentは、Androidアプリ内のコンポーネント間の通信を仲介するメカニズムです。
- Bundleの仕組み: Bundleは、キーと値のペアを格納するための軽量なコンテナです。
- Serializableインターフェース: オブジェクトをバイトストリームに変換し、逆変換できるようにするインターフェースです。
- Parcelableインターフェース: Androidプラットフォームで効率的にオブジェクトをマーシャリングするためのインターフェースです。
ご希望に応じて、より具体的なコード例や、特定のケースに合わせた解説も可能です。
- カスタムクラスをIntentに渡すにはどうすれば良いですか?
- startActivityForResult()を使って結果を受け取るにはどうすれば良いですか?
- サービスを使ってデータをやり取りする方法は?
- BroadcastReceiverを使ってデータをやり取りする方法は?
ViewModel を使う
- MVVM パターン: Model-View-ViewModel パターンの ViewModel を利用することで、データの生存期間を長くし、アクティビティの再生成時にもデータが失われないようにすることができます。
- LiveData: LiveData を使って、データの変化を監視し、UI を自動的に更新することができます。
- SharedViewModel: アクティビティ間でデータを共有する必要がある場合、SharedViewModel を使うことで、複数の ViewModel から同じデータを参照することができます。
// ViewModel
class SharedViewModel : ViewModel() {
val userName = MutableLiveData<String>()
}
// Activity A
viewModel.userName.value = "太郎"
// Activity B
viewModel.userName.observe(this) { name ->
textView.text = name
}
Room を使う
- データベース: Room を使うことで、データを永続化し、複数のアクティビティからアクセスすることができます。
- LiveData: Room は LiveData と連携することで、データベースの変更を UI に反映することができます。
// データベース
@Entity
data class User(
@PrimaryKey val uid: Int,
val firstName: String,
val lastName: String
)
// DAO
@Dao
interface UserDao {
@Query("SELECT * FROM user")
fun getAll(): LiveData<List<User>>
}
EventBus を使う
- 公開-購読: EventBus (Otto, GreenRobot EventBus など) を使うことで、イベントを発行し、他のオブジェクトがそのイベントを購読することで、非同期にデータをやり取りすることができます。
- 疎結合: イベントバスを使うことで、コンポーネント間の結合度を低くすることができます。
// イベント
class UserUpdatedEvent(val user: User)
// イベントの発行
EventBus.getDefault().post(UserUpdatedEvent(user))
// イベントの購読
EventBus.getDefault().register(this)
override fun onEvent(event: UserUpdatedEvent) {
// イベントを受け取って処理
}
SharedPreferences を使う
- 単純なデータ: SharedPreferences は、小さなデータを永続化するためのシンプルな方法です。
- 設定データ: アプリの設定情報を保存するのに適しています。
val sharedPreferences = getSharedPreferences("MyPrefs", Context.MODE_PRIVATE)
val editor = sharedPreferences.edit()
editor.putString("u sername", "太郎")
editor.apply()
どの方法を選ぶべきか?
- データの寿命: データが一時的なものか、永続的なものか。
- データの複雑さ: 単純なデータか、複雑なオブジェクトか。
- コンポーネント間の結合度: 疎結合にしたいか、密結合でも問題ないか。
- データの更新: データが頻繁に更新されるか、静的なデータか。
これらの要素を考慮して、適切な方法を選択してください。
- Intent, Bundle: アクティビティ間でデータを直接渡す
- ViewModel: データの生存期間を長くし、UI との連携を強化
- Room: データベースを利用し、永続的なデータを扱う
- EventBus: イベントベースの非同期通信
- SharedPreferences: シンプルなデータを永続化
- 各方法には、より詳細な設定や注意点があります。
- Android Jetpack Compose では、State を使って状態を管理する方法が推奨されています。
- ViewModel と LiveData の違いは何ですか?
- Room で複雑なクエリを実行するにはどうすれば良いですか?
- EventBus のメリットとデメリットは何ですか?
- SharedPreferences の代わりに別の方法を使うべきケースは?
android android-intent android-activity