IT/안드로이드+JAVA

[안드로이드] 액티비티간의 통신 putExtra, getExtra (설명, 예제)

안경 쓴 귀니 2016. 5. 21. 13:06
반응형

[안드로이드] 액티비티간의 통신 putExtra, getExtra


인텐트는 액티비티간에 인수와 리턴값을 전달하는 도구로 사용된다. 이때는 주로 Bundle 타입의 Extra를 활용하는데 이름과 값의 쌍으로 된 임의 타입의 정보를 원하는 개수만큼 저장한다. Extra는 쉽게 말해서 인텐트내의 정보 저장 주머니이며 호출하는 쪽이나 받는 쪽에서 자유롭게 액세스 가능하다. 다음은 Extras에 값을 저장하는 메서드 중 일부이다. 거의 모든 타입에 대해 오버로딩되어 있으며 배열이나 심지어 시리얼라이징 가능한 객체까지도 저장할 수 있다.


Intent putExtra (String name, int value)

Intent putExtra (String name, String value)

Intent putExtra (String name, boolean value)


name은 전달하는 인수에 대한 이름이되 중복되지만 않으면 자유롭게 붙일 수 있다. 가급적이면 인수의 의미를 명확하게 설명할 수 있는 이름을 붙이는 것이 좋다. Extras에 저장된 값은 다으 메서드로 꺼낸다.


int getIntExtra (String name, int defaultValue)

String getStringExtra(String name)

boolean getBooleanExtra (String name, boolean defaultValue)


값이 전달되지 않았을 경우 두 번째 인수로 지정한 디폴트가 리턴되며 문자열의 경우 null이 리턴된다. Extras는 입력뿐만 아니라 액티비티의 리턴값을 돌려줄 때도 사용한다. 적당한 이름으로 값을 넣어 두면 호출원에서 약속된 이름으로 리턴값을 꺼내 사용한다.

액티비티로 인수를 전달하고 계산된 결과를 리턴값으로 돌려받는 예제를 만들어 보자. 인수와 리턴값은 인텐트를 통해 전달할 수 있지만 이 외에도 누가 호출했는지에 대한 정보가 포함되어야 한다. 단순히 호출만 하는 것이 아니라 결과를 돌려 받아야 하므로 액티비티를 호출하는 메서드가 달라진다. 리턴값을 돌려주는 액티비티는 다음 메서드로 호출한다.


void startActivityForResult (Intent intent, int requestCode)


두 번째 인수가 하나 더 추가되는데 호출한 대상을 나타내는 식별자이며 리턴 시에 누구에 대한 리턴인지 구분할 때 사용한다. 여러 액티비티를 호출할 경우 리턴을 받는 메서드에서 어떤 액티비티에 대한 리턴인지 구분할 수 있어야 하므로 호출되는 액티비티별로 고유의 번호를 붙인다. 0 이상의 중복되지 않는 정수를 넘기되 음수를 넘길 경우는 리턴을 ㅂ다지 않겠다는 뜻이다. 호출된 액티비티가 종료되면 다음 메서드가 호출된다.


void onActivityResult (int requestCode, int resultCode, Intent data)


requestCode는 액티비티를 호출할 때 전달한 요청코드이며 resultCode는 액티비티의 실행 결과이다. 이 둘을 분석해 보면 누구에 대한 호출이 어떻게 처리되었는지 알 수 있다. 리턴값은 data안의 Extras를 읽어 구한다. 다음 예제는 간단한 문자열 편집 액티비티를 구현한 것이다.


main_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"/>

<Button
android:id="@+id/btnedit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="mOnClick"
android:text="Edit"/>

</LinearLayout>




MainActivity.java

package com.parkeunsu.extratest;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
TextView mText;
final static int ACT_EDIT = 0;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
mText = (TextView)findViewById(R.id.text);
}

public void mOnClick(View v) {
switch (v.getId()) {
case R.id.btnedit:
Intent intent = new Intent(this, ActEdit.class);
intent.putExtra("TextIn", mText.getText().toString());
startActivityForResult(intent, ACT_EDIT);
break;
}
}

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case ACT_EDIT:
if(resultCode == RESULT_OK) {
mText.setText(data.getStringExtra("TextOut"));
}
break;
}
}
}



메인 액티비티에는 텍스트뷰 하나와 버튼을 배치해 두었다. 텍스트뷰는 디폴트로 Hello World! 라는 문자열을 표시하는데 단순히 문자열을 보여주기만 하므로 이 액티비티에서는 직접 편집할 수 없다. 그래서 문자열을 편집하는 별도의 서브 액티비티인 ActEdit을 호출한다. 편집 액티비티는 요철 코드 0번을 ACT_EDIT 상수로 정의해 두었으며 버튼의 클릭 리스너에서 호출한다. TextIn이라는 이름을 가지는 Extras로 텍스트뷰의 문자열을 읽어 인텐트에 저장하고 startActivityForResult 메소드로 ActEdit 액티비티를 호출했다. 이때 요청 번호는 0번이다. 문자열 편집 액티비티는 에디트 하나와 버튼 두 개가 배치되어 있으며 코드는 다음과 같다.



act_edit.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<EditText
android:id="@+id/stredit"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

<Button
android:id="@+id/btnok"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="mOnClick"
android:text="OK"/>

<Button
android:id="@+id/btncancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="mOnClick"
android:text="Cancel"/>

</LinearLayout>



ActEdit.java

package com.parkeunsu.extratest;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;

public class ActEdit extends AppCompatActivity {
EditText mEdit;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_edit);

mEdit = (EditText)findViewById(R.id.stredit);

Intent intent = getIntent();
String text = intent.getStringExtra("TextIn");
if(text != null) {
mEdit.setText(text);
}
}

public void mOnClick(View v) {
switch (v.getId()) {
case R.id.btnok:
Intent intent = new Intent();
intent.putExtra("TextOut", mEdit.getText().toString());
setResult(RESULT_OK, intent);
finish();
break;
case R.id.btncancel:
setResult(RESULT_CANCELED);
finish();
break;
}
}
}



onCreate에서 getIntent() 메서드로 액티비티로 전달된 인텐트를 구한다. 이 안에는 액티비티가 취해야 할 동작, 데이터, 추가 정보가 들어 있다. 편집 액티비티는 다른 정보를 사용하지 않으며 추가 정보에서 편집 대상 문자열만 사용한다. 인텐트의 getStringExtra 메서드를 호출하여 TextIn이라는 이름으로 전달된 문자열을 읽어 에디트를 초기화한다.



 < 최초 시작 시


최초 시작 시에는 호출원에서 문자열이 보이지만 사용자가 문자열을 직접 편집할 수 있다. OK 버튼을 누르면 편집한 결과를 다시 호출원으로 돌려준다. 결과를 리턴할 때도 인텐트를 사용하는데 새 인텐트 객체를 생성하고 사용자가 편집한 문자열을 추가 정보의 TextOut 이라는 이름으로 저장해 놓는다. 그리고 다음 메서드로 결과를 대입한다.


void setResult (int resultCode, Intent data)


resultCode는 인텐트의 작업 결과이다. 편집을 완료했으면 RESULT_OK를 리턴하고 취소했으면 RESULT_CANCEL을 리턴한다. 두 번째 인수로 리턴값이 실려 전달된다. 결과를 대입했으면 finish 메서드를 호출하여 액티비티를 종료한다. Cancel 버튼을 눌렀다면 RESULT_CANCEL만 넘기며 추가 정보는 전달할 필요가 없다. Back 버튼을 눌러 액티비티를 종료하면 Cancel을 누른 것과 같다.


호출언은 액티비티의 실행 결과를 onActivityResult 메서드로 전달받는다. 요청 코드와 처리 결과, 인텐트가 인수로 전달되므로 이 정보를 참조하여 액티비티의 동작 결과를 사용한다. 0번 요청에 대해 RESULT_OK가 왔으면 텍스트를 편집하여 리턴했다는 뜻이다. 인텐트로 전달된 추가 정보 중 TextOut 이름을 가지는 문자열을 읽어 텍스트뷰에 대입한다. 텍스트뷰에 편집된 문자열이 나타난다.





이 예제의 경우는 호출되는 액티비티가 하나밖에 없으므로 사실 onActivityResult에서 굳이 요청코드를 볼 필요가 없다. 그러나 한 액티비티에서 여러 개의 서브 액티비티를 호출한다면 요청 코드로 리턴값의 의미를 구분해야 한다. 모든 액티비티가 리턴할 때 onActivityResult 메서드를 호출하므로 요청 코드가 없다면 누가 리턴했는지 구분할 방법이 없다.



[출처] 안드로이드 프로그래밍 정복 개정4판




공감 버튼 꾸욱- 눌러주세요

힘이 됩니다!ㅎㅎ

로그인 없어도 가능합니다~^^*

반응형