Androidアプリでアクティビティ間でデータをやり取りする方法 (日本語)

2024-08-23

Androidアプリにおいて、アクティビティ間でデータをやり取りする方法はいくつかあります。ここでは、そのうち2つの主要な方法について説明します。

Intentを使用する

Intentは、アプリケーション内のコンポーネント間でメッセージやデータを伝達するためのオブジェクトです。アクティビティ間でデータをやり取りする最も一般的な方法です。

方法:

  1. データの格納:

    • Intentオブジェクトを作成します。
    • putExtra()メソッドを使用して、キーと値のペアでデータを格納します。さまざまなデータ型(String、int、boolean、Serializable、Parcelableなど)を格納できます。
    val intent = Intent(this, SecondActivity::class.java)
    intent.putExtra("name", "John")
    intent.putExtra("age", 30)
    
  2. アクティビティの起動:

    startActivity(intent)
    
    • 次のアクティビティでは、getIntent()メソッドを使用してIntentを取得し、getStringExtra()などのメソッドを使用してデータを取り出します。
    val name = intent.getStringExtra("name")
    val age = intent.getIntExtra("age", 0)
    

Bundleを使用する

  1. Bundleの作成:

    • Bundleオブジェクトを作成し、putString()putInt()などのメソッドを使用してデータを格納します。
    val bundle = Bundle()
    bundle.putString("name", "John")
    bundle.putInt("age", 30)
    
  2. Intentへの追加:

    • IntentオブジェクトのputExtras()メソッドを使用して、Bundleを格納します。
    val intent = Intent(this, SecondActivity::class.java)
    intent.putExtras(bundle)
    
  3. 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()メソッドで、作成したBundleIntentに格納します。
// 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()メソッドを使って、キーに対応する値を取り出します。

どちらを使うべきか?

  • シンプルなデータの受け渡し: IntentputExtra()メソッドで直接データを格納する方が簡単です。
  • 複雑なオブジェクトの受け渡し: SerializableParcelableインターフェースを実装したカスタムオブジェクトをIntentに渡す場合は、Bundleを使う方が便利です。
  • サービスBroadcastReceiverを使って、アクティビティ間でデータをやり取りすることも可能です。
  • 上記のコードはKotlinで記述されています。Javaでも同様のことができます。
  • データの種類によって、適切なデータ型を使ってputExtra()putExtras()メソッドに渡す必要があります。
  • SerializableParcelableインターフェースについては、より複雑なオブジェクトを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



AndroidでListViewにおける画像の遅延読み込みのコード例

ListViewはAndroidアプリで頻繁に使用されるUIコンポーネントですが、大量の画像を表示する場合、パフォーマンスが低下する可能性があります。これを回避するために、画像の遅延読み込み(lazy loading)を導入します。遅延読み込みとは、必要なときにのみ画像をロードする手法です。ListViewのスクロール時に表示範囲内の画像のみを読み込むことで、アプリの起動時間を短縮し、ユーザー体験を向上させます。...


Androidにおける横向きモード無効化のプログラミング例の詳細解説

AndroidManifest. xmlファイルでの設定最も一般的な方法は、AndroidManifest. xmlファイルでアクティビティの android:screenOrientation 属性を設定することです。portrait: 縦向きのみ許可...


Androidで画面サイズをピクセル単位で取得する方法

Androidアプリで画面サイズをピクセル単位で取得するには、以下の方法を使用します:DisplayMetricsクラスを使用して、デバイスのディスプレイに関する情報を取得します。WindowManagerクラスを使用して、アクティビティのウィンドウに関する情報を取得します。...


Android ソフトキーボードのプログラム的制御: コード解説

Android アプリケーションにおいて、ソフトキーボードをプログラム的に閉じるまたは隠す方法は、主に InputMethodManager クラスを利用します。このクラスは、入力メソッドの管理を担当するシステムサービスです。EditText インスタンスを取得します。これは、ソフトキーボードを表示する対象となるビューです。...


Android エミュレータの遅さについての解説と高速化方法

Android エミュレータが遅い理由:Android エミュレータは仮想マシン上で Android OS を実行するため、実際のデバイスよりも処理速度が遅くなります。主な原因は以下です。仮想化オーバーヘッド: 仮想化ソフトウェアがハードウェアとゲスト OS (Android) の間で仲介する際に発生するオーバーヘッド。...



android intent activity

Androidアプリでアクティビティの状態を保存する代替方法

Androidアプリでは、ユーザーがアプリを一時停止したり、画面を回転させたりすると、アクティビティが再作成されます。このとき、アクティビティの現在の状態を保持するために、saveInstanceState()メソッドを使用します。オーバーライドする: アクティビティクラスでsaveInstanceState()メソッドをオーバーライドします。


AndroidでTextViewのテキストを水平・垂直方向に中央揃えするコード例

android:gravity属性を使用します。水平方向の中央揃え: android:gravity="center"水平方向の中央揃え: android:gravity="center"TextViewオブジェクトを取得し、setGravityメソッドを使用します。水平方向の中央揃え: textView


Android画面回転時のActivity再起動に関するコード例解説

Androidでは、デバイスの画面が回転すると、デフォルトではActivityが再起動されます。これは、画面の向きが変わった際に、アプリが適切にレイアウトやリソースを調整するためです。レイアウト調整: 画面の向きが変わることで、UI要素の配置やサイズが適切でない場合があるため、再起動してレイアウトを再描画します。


AndroidでBitmapオブジェクトに画像をロードする際のOutOfMemoryErrorについて

OutOfMemoryErrorは、Androidアプリで画像をBitmapオブジェクトにロードする際に発生する一般的な問題です。これは、デバイスのメモリが不足しているため、画像を完全にロードすることができない場合に起こります。画像サイズが大きい: 高解像度またはサイズが非常に大きな画像をロードすると、メモリ不足を引き起こす可能性があります。


AndroidアプリでSQLiteデータベースを使用する方法

SQLite は、軽量で使いやすいオープンソースのデータベースエンジンです。Android には SQLite が標準搭載されているため、追加のライブラリをインストールする必要はありません。SQLite データベースを作成するには、以下の手順が必要です。