diadia

興味があることをやってみる。自分のメモを残しておきます。

起動するActivityへデータを渡す

やりたいこと

起動するアクティビティへデータを渡す場合には、Intentオブジェクトにデータを追加してアクティビティを起動する。そして起動したアクティビティ内でデータを取り出す。渡したいデータの型が自作の場合には普段どおりにはデータを渡すことはできない。このデータをアクティビティで渡したいがどうすればよいのか?

基本的なデータ型の受け渡し方:
kotlin : 画面遷移先でintentに格納データを取り出す方法 - diadia

方法

データを渡す方法としてシリアライザを使うかパラセラブルを使うかの2種類の方法がある。

1. Serializableを使う方法

受け渡したいクラスにSerializableを実装する旨の資料

How to pass data between activities with android Serializable

putExtra()メソッド内でSerializableをキャストする旨の資料

android - Get Serializable ArrayList on Intent fragment - Stack Overflow

データの受け渡しの全体の流れの資料

Activity間のObject引き渡し - Qiita

サンプルコード1

渡したいデータ型にSerializableをimplementする。そしてintentに付与する。

そしてIntent#getSerializableExtra()で取り出す。

//dataクラスにSerializableを実装
data class MyData{
    var id: Int
    var name: String 
}:Serializable

//受け渡すデータを生成
val myData = MyData(id=3, name="yokogoshi")


//アクティビティの起動
val intent = Intent(this, NextActivity::class.java)
intent.putExtra("keyForMyData", myData)
startActivity(intent)


//起動したアクティビティでのデータの受取
val bundle = intent.extras!!
val myData = bundle.getSerializableExtra("keyForMyData")

サンプルコード2

Intent#putExtra()メソッドにてSerializableをキャストする。

//dataクラスにSerializableを実装
data class MyData{
    var id: Int
    var name: String 
}

//受け渡すデータを生成
val myData = MyData(id=3, name="yokogoshi")


//アクティビティの起動
val intent = Intent(this, NextActivity::class.java)
intent.putExtra("keyForMyData", myData as Serializable)
startActivity(intent)


//起動したアクティビティでのデータの受取
val bundle = intent.extras!!
val myData = bundle.getSerializableExtra("keyForMyData")

2. Palacelableを使う方法

実装方法

単純にbundle.putPrcelable()メソッドを使って受け渡したいオブジェクトをBundleオブジェクトに格納することができない。 その前にparacelableインターフェースを使う必要があるようだ。実装は以下の通り。

実装概要

  1. Palacelableを実装したデータクラスを作成する。 このデータクラスにはwriteToParcelとdescribeContentsをオーバーライドしたものを準備する必要がある。

  2. そしてインテントに送りたいデータオブジェクトを作成しインテントに格納する。

  3. 画面遷移した先でデータオブジェクトを取得する。

受け渡し用のデータクラスの作成

import android.os.Parcel
import android.os.Parcelable

data class AccountsList(val accounts: Array<Account!> ) : Parcelable {

  //writeToParcelをオーバーライド
  override fun writeToParcel(parcel: Parcel, flags: Int) {
    parcel.writeParcelable(accounts, flags)        
  }

  //describeContentsをオーバーライド
  override fun describeContents(): Int = 0



  companion object {
    val CREATOR: Parcelable.Creator<AccountsList> = object : Parcelable.Creator<AccountsList>{
    override fun newArray(size: Int): Array<AccountsList?> = arrayOfNulls<AccountsList>(size)
    override fun createFromParcel(source: Parcel): AccountsList = AccountsList(source)
        }
    }

    constructor(source: Parcel):this(
            source.readParcelable(AccountsList::class.java.classLoader)
    )

}

データの受け渡しと引き出し

val intent = Intent(this.activity, NewActivityName::class.java)
val bundle = Bundle()
//Activityに渡したいデータインスタンスを生成
val parcel = ParcelObjectName(titleValue,descriptionValue)


bundle.putParcelable("key", parcel)
intent.putExtra("Bundle", bundle)
startActivity(intent)



val bundle = intent.getBundleExtra("Bundle")
val object = bundle.getParcelable<ParcelObjectName>("key")

参考資料

Android Kotlin: Use Parcelable to pass object to another activity

Android — Parcelable en Kotlin

Android SDKの,ParcelableとSerializableの違いを比較 - Intentで独自オブジェクトを運搬する際,役立つのはどちら? - 主に言語とシステム開発に関して

android - How to Pass custom object via intent in kotlin - Stack Overflow