안드로이드

[Parcelable 및 Bundle]

란서 2021. 7. 1. 15:56

[Parcelable 및 Bundle] 공부하기

Parcelable 및 Bundle 객체는 IPC/바인더 트랜잭션과 같은 프로세스 경계 전반에서 Intent(인텐트)가 있는 활동 간에 사용하고 구성 변경 시(ex_화면 전환 및 앱 이동) 일시적인 상태를 저장하기 위한 것. 

 

참고 : Parcel은 범용 직렬화 메커니즘이 아니므로 parcel 데이터를 디스크에 저장하거나 네트워크를 통해 전송해서는 안 된다.

 

활동 간 데이터 전송

앱이 새 활동을 시작하면서 startActivity(android.content.Intent)에 사용할 Intent 객체를 생성할 때 putExtra(java.lang.String, java.lang.String) 메서드를 사용하여 매개변수를 전달할 수 있습니다.

//보내는 측
val intent = Intent(this, MyActvitiy::class.java).apply{ 
	putExtra("media_id", "a1b2c3") //키String_값String 설정 
}

startActivity(intent)

//받는 측
val getIntent = intent
val msg = intent.extras?.getString("media_id") // msg == "a1b2c3"


 

OS는 인텐트의 기본 Bundle을 묶은 다음, 새 활동을 생성하고 번들을 풀며 인텐트를 새 활동에 전달한다.

 

Bundle 클래스를 사용하여 Intent 객체에서 OS에 알려진 프리미티브(기본형 : Int, Int?, Double, Long? 등등)를 설정하는 것이 좋다. Bundle 클래스는 Parcel을 사용하는 마샬링 및 언마샬링에 고도로 최적화 되어있다.

 

활동 간에 프리미티브 이외에 합성 또는 복합 객체를 전달할 수 있다.
  • 맞춤 클래스는 Parcelable을 구현한다.
  • 적절한 writeToParcel(android.os.Parcel, Int) 메서드를 override한다.
  • CREATOR라는 null이 아닌 필드도 생성 한다.
  • CREATOR은 Parcel을 현재 객체로 다시 변환하는 데 createFromParcel() 메서드를 사용하는 Parcelable.Creator 인터페이스를 구현한다.

 

참고 : 인텐트를 통해 데이터를 전송할 때 데이터 크기를 몇 KB로 제한해야 한다. 너무 많은 데이터를 전송하면 시스템에서 TransactionTooLargeException 예외가 발생한다.
MainActivity
//MainActivity
package com.example.parcelablekt

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.EditText

class MainActivity : AppCompatActivity() {
    private lateinit var btn : Button
    private lateinit var et_book : EditText
    private lateinit var et_name : EditText
    private lateinit var et_year : EditText
    private lateinit var et_bestSeller : EditText

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        btn = findViewById(R.id.btn_move)
        et_book = findViewById(R.id.et_bookName)
        et_name = findViewById(R.id.et_name)
        et_year = findViewById(R.id.et_year)
        et_bestSeller = findViewById(R.id.et_bestSeller)

        btn.setOnClickListener {
            val intent = Intent(this, SubActivity::class.java).apply {
                putExtra(
                    "Result",
                    Book(
                        et_book.text.toString(),
                        et_name.text.toString(),
                        et_year.text.toString(),
                        et_bestSeller.text.toString()
                    )
                )
            }
                startActivity(intent)
        }
    }
}

 

SubActivity
//SubActivity
package com.example.parcelablekt

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView

class SubActivity : AppCompatActivity() {

    private lateinit var tv_book : TextView
    private lateinit var tv_name : TextView
    private lateinit var tv_year : TextView
    private lateinit var tv_bestSeller : TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sub)


        tv_book = findViewById(R.id.tv_bookName)
        tv_name = findViewById(R.id.tv_name)
        tv_year = findViewById(R.id.tv_year)
        tv_bestSeller = findViewById(R.id.tv_bestSeller)

        val getIntent = intent
        val book = intent.getParcelableExtra<Book>("Result")!!

        val (bookName, name, year, bestSeller) = book

        val textViewList = listOf(tv_book, tv_name, tv_year, tv_bestSeller)
        val stringList = listOf(bookName, name, year, bestSeller)

        for((index,value) in textViewList.withIndex()) {
            value.text = stringList[index]
        }
    }
}

 

Book Class
//Book Class
package com.example.parcelablekt

import android.os.Parcelable
import kotlinx.parcelize.Parcelize


//kotlin 플러그인 'kotlin-parcelize' 적용
@Parcelize
data class Book (val book: String?, val name : String?, val year: String?, val bestSeller: String?) : Parcelable

 

테스트 영상

 

 

 

※ Serializable 와 Parcelable 의 차이점을 다음에 정리하자.

https://www.charlezz.com/?p=823 

 

Parcelable과 Serializable 비교 | 찰스의 안드로이드

Serializable은 분명히 개발자 입장에서는 편합니다. 인터페이스 구현만 하면되니까요. 하지만 앱 사용자에게는 퍼포먼스저하와 베터리 드래인이라는 큰 단점을 안겨 줍니다. 조금은 귀찮더라도 Se

www.charlezz.com