Android/note

[Android] EditText 의 데이터 Intent 로 받아오기

김 안개 2023. 9. 15. 14:23

[ 문제 상황 ]

EditText 를 통해 사용자 입력을 받아 Intent 로 데이터를 넘겨 받아오는 과정에서 getStringExtra()를 사용하면 데이터가 null 이 되는 것을 알게되었다.

이유는 무엇일까?

 

[ 해결 과정 ]

디버깅을 통해 일단 (1) 데이터가 잘 전달되는지 (2) 잘 받아와지는지 확인하였다.

 

1) 데이터가 잘 전달되는지 확인하기

moveTopicList 는 TopicListFragment 로 데이터를 전달해주는 Intent 객체이다.

mExtras 를 확인해보면 Bundle 안에 topic=주제입력 으로 잘 들어가있는 것을 확인할 수 있다.

 

2) 데이터가 잘 받아와지는지 확인하기

 

데이터를 받는 화면인 TopicListFragment 에서 디버깅해보면 일단 해당 Intent 의 mExtras 에 데이터가 있는 것을 확인할 수 있다.

 

 

근데 저장된 topic 을 보면 넘어와야 할 "주제입력"이 아닌 null 이 된 것을 볼 수 있다.

 

왜지? 이전에는 잘 사용했는데 말이야! 그래서 이전의 코드와 현재 코드를 비교해보았다.

3) 수정 전 getStringExtra() 를 사용할 때의 코드 살펴보기

// TopicDialogActivity.kt

val topic = Topic(inputText.text.toString(), selectedColor, DateFormat.currentDateFormat())

if (StringFormat.checkLengthOfTopic(topic.topic.length)) {
	val moveTopicList = Intent(this, TopicListFragment::class.java)
	moveTopicList.putExtra("topic", topic.topic)
	moveTopicList.putExtra("color", topic.color)
	moveTopicList.putExtra("date", topic.registDate)
	setResult(TopicListFragment.INTENT_RESULT_TOPIC, moveTopicList)
	finish()
}

 

Topic 객체를 생성한 후 -> 해당 객체의 변수에 접근하여 putExtra 를 통해 Intent 에 데이터를 넣었다.

 

4) 수정 후 지금 코드 살펴보기

// TopicListFragment.kt

val inputTopic = inputText.text

if (StringFormat.checkLengthOfTopic(inputTopic.length)) {
	val moveTopicList = Intent(this, TopicListFragment::class.java)
	moveTopicList.putExtra("topic", inputTopic)
	setResult(TopicListFragment.INTENT_RESULT_TOPIC, moveTopicList)
}

 

Topic 객체를 미리 만들 필요가 없다고 생각되어서 EditText 를 통해 입력받은 데이터만 전달하는 것으로 수정했다.

 

달라진 부분은 putExtra() 메서드에 argument 를 넣을 때
(1) 객체의 변수(String 타입)를 넣었는지
(2) EditText 의 getText() 를 통해 바로 데이터를 넣었는지

 

이 부분이 달라져서 문제가 발생했던 것이다.

 

5) putExtra() 메서드 살펴보기

가장 먼저 수정 전 코드에서 Topic의 topic 변수는 String 타입이기 때문에 Intent 에 putExtra 를 하게되면 

 

// Intent.java

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

 

위와 같이 value 의 타입이 String 인 putExtra 를 통해 Bundle 에 putString() 으로 데이터를 저장하게 된다. 

그러므로 String 의 값이 저장되어 있었기 때문에 getStringExtra() 로 데이터에 접근하여 받아올 수 있었다.

 

하지만 수정 후의 코드에서는 가장 먼저 EditText 의 데이터를 .getText() 를 통해 받아왔는데

 

// EditText.java

public Editable getText() {
    CharSequence text = super.getText();
    
    // This can only happen during construction.
    if (text == null) {
		return null;
	}
    
    if (text instanceof Editable) {
		return (Editable) super.getText();
	}
    
	super.setText(text, BufferType.EDITABLE);
	return (Editable) super.getText();
}

 

CharSequence 타입으로 데이터가 저장되어 지는 것을 알 수 있다.

 

Intenet 에 putExtra() 메서드를 통해 데이터를 넣어보려해도 나는 value 의 타입이 String 이 아닌 CharSequence 타입을 파라미터로 받는 putExtra() 가 호출되었던 것이다.

 

// Intent.java

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

 

CharSequence 타입의 데이터를 Intent 에서 받아오려면 

 

// Intent.java

public @Nullable CharSequence getCharSequenceExtra(String name) {
	return mExtras == null ? null : mExtras.getCharSequence(name);
}

 

getCharSequenceExtra() 를 사용해야 한다.

 

확인 차 getCharSequenceExtra() 를 통해 다시 테스트를 해보자면

 

 

이번 입력 데이터는 "주제 입력 테스트"

 

 

topic 부분에 null 이 아닌 "주제 입력 테스트" 가 잘 들어온 것을 확인할 수 있다!

[ 결론 ]

데이터의 타입이 일치하지 않아서(CharSequence != String) Intent 의 getStringExtra() 를 통해서는 데이터를 받아올 수 없었던 것이다.

getStringExtra() 가 아닌 getCharSequenceExtra() 를 사용하면 데이터를 받아볼 수 있다!