본문 바로가기
개발/Android

[Android] Intent와 Bundle 무엇이 다를까? (feat. 객체 전달)

by tempus 2022. 4. 29.
반응형

흔히 Activity와 Fragment 간에 데이터를 전달할 때 우리는 IntentBundle을 사용해서 데이터를 전달합니다. 하지만 두 개의 용도는 명확히 다릅니다.

 

Intent저장이 아닌 전달하는 수단으로의 객체이고 Bundle 상태/값 등을 저장하기 위한 객체입니다. Bundle은 Map의 형태로 되어있습니다.

 

Intent에서 데이터를 전달할 때 다음과 같은 두 가지 코드를 보셨을 겁니다.

val intent = Intent()
intent.putExtra("key","value")
val intent = Intent()

val bundle =Bundle()
bundle.putString("key","value")
intent.putExtra("bundle",bundle)

위의 두 코드의 결과는 같습니다. 하나는 Intent내부의 putExtra() 함수를 통해 value를 넘겨주는 것이고 하나는 Bundle을 만들고 그 안에 데이터를 넣어서 Intent를 통해 전달을 해줍니다. 두 개의 차이는 무엇이 있을까요?

 

Intent의 내부 함수를 보면 보시다시피 Bundle을 통해 데이터를 전달하고 있습니다.

public @NonNull Intent putExtra(String name, @Nullable String value) {
    if (mExtras == null) {
        mExtras = new Bundle();
    }
    mExtras.putString(name, value);
    return this;
}

 

Bundle은 내부적으로 Map을 활용해 바로 데이터를 넣어주고 있습니다.

ArrayMap<String, Object> mMap = null;

public void putString(@Nullable String key, @Nullable String value) {
    unparcel();
    mMap.put(key, value);
}

 

차이점은 보면 결국에는 Bundle을 통해 보내주지 않고 Intent내부 함수를 사용하면 내부적으로 Bundle을 생성해서 보내줍니다. 비용적인 측면에서 보았을 때는 후자가 나을 것 같지만 가독성이나 코드 길이 면에서는 전자가 나을 수 있겠다는 생각이 들었습니다.

 

추가적으로, 그렇다면 객체를 전달하고 싶다면 어떻게 해야 할까요? 일단 객체를 프로세스 간 전달하기 위해서는 직렬화 과정을 거쳐야 하기 때문에 Serializable이나 Parcelable을 구현한 클래스를 통해 보내주어야 합니다. (일반적으로 Paraceable은 리플렉션 과정이 없기 때문에 Serializable 보다 10배 빠르다고 합니다. 참고 - Parcelable vs Serializable)

 

Serializable를 통해 객체 전달하기

data class SimpleData(
    val name : String
) : Serializable

그리고 MainActivity에서 다음과 같이 전달을 해주면

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

        val intent= Intent(this, MainActivity2::class.java)

        val bundle = Bundle()
        bundle.putSerializable("key", SimpleData(name = "hi"))
        intent.apply {
            this.putExtra("bundle", bundle)
        }

        startActivity(intent)

    }
}

MainActivity2에서 다음과 같이 받아서 쓸 수 있습니다.

class MainActivity2 : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main2)

        val bundle = intent.getBundleExtra("bundle")
        val simpleData = bundle?.getSerializable("key") as SimpleData
    }
}

 

Parcelable을 통해 객체 전달하기

사용하기 위해 Module 수준에서 plugin을 추가해야 합니다. (Project 수준 X)

plugins {
    id 'kotlin-parcelize'
}

그리고 데이터 클래스를 다음과 같이 구현해줍니다.

@Parcelize
data class SimpleData(
    val name : String
) : Parcelable

그리고 MainActivity에서 다음과 같이 전달을 해주면

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

        val intent= Intent(this, MainActivity2::class.java)

        val bundle = Bundle()
        bundle.putParcelable("key", SimpleData(name = "hi"))
        intent.apply {
            this.putExtra("bundle", bundle)
        }

        startActivity(intent)

    }
}

MainActivity2에서 다음과 같이 받아서 쓸 수 있습니다.

class MainActivity2 : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main2)

        val bundle = intent.getBundleExtra("bundle")
        val name = bundle?.getParcelable<SimpleData>("key")?.name

    }
}

 

정리하자면 다음과 같습니다.

  • Intent는 데이터를 전달하는 수단으로의 객체이고 Bundle은 상태나/값을 저장하기 위한 Map형태로 된 객체이다.
  • bundle을 통해 객체를 전달하고 싶을 때는 직렬화과정이 필요하기에 Serializable이나 Parcelable를 사용한다.

 

반응형

댓글


loading