안드로이드 애플리케이션에는 4대 기본 구성요소가 있다.
앱을 안드로이드 디바이스에 설치하면 시스템은 위 4대 구성요소에 대한 정보를 요구하며, 앱은 이들에 대한 정보를 AndroidManifest.xml 파일에 가지고 있다.
액티비티는 안드로이드의 4대 컴포넌트 중 하나인 만큼 액티비티의 구성과 동작에 대해 이해하는 것은 매우 중요하다.
안드로이드 애플리케이션에서 하나의 화면은 하나의 액티비티라고 할 수 있다. 화면을 전환하는 행위는 액티비티를 띄우고 닫는 행위이다.
새로운 액티비티를 화면에 띄울 때 startActivity() 메소드를 사용한다. 이 메소드는 단순히 화면을 띄우는 기능만 한다. 하지만 여러 개의 액티비티를 띄우거나 새로 띄운 액티비티에서 기존의 액티비티로 돌아올 때 응답을 받아 처리하거나, 이 응답이 어떤 액티비티에서 온 것이 구분하는 등의 일을 해야할 때가 있다. 이 때에는 startActivityForResult()를 사용하면 된다.
startActivityForResult(Intent intent, int requestCode)
requestCode는 여러개의 액티비티를 띄웠을 때 원래의 액티비티로 보내오는 응답이 어떤 액티비티에서 온 것인기 구분하기 위해 사용한다.
구체적으로 어떻게 사용하는지 프로젝트를 만들어보자.
먼저, 새로운 프로젝트를 만들면 MainActivity.java와 activity_main.xml 두 개의 파일이 자동으로 생성된다. 여기에 추가적으로 MenuActivity라는 새로운 액티비티를 추가한다.
그러면 AndroidManifest.xml에 새로운 activity 태그가 등록이 된다. 여기에 두 개의 속성을 추가한다.
<activity
android:name=".MenuActivity"
android:label="메뉴 액티비티"
android:theme="@style/Theme.AppCompat.Dialog">
</activity>
label은 화면의 타이틀, theme는 테마를 설정하는 속성이다. theme를 Dialog로 설정했기 때문에 대화상자 형식의 액티비티가 된다.
먼저 activity_menu.xml 파일에 다음 코드를 작성한다.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MenuActivity">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
android:text="돌아가기"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
버튼 1개만 있는 단순한 레이아웃이다.
MenuActivity.java 파일에는 버튼을 누르면 원래의 화면으로 응답과 부가 데이터를 보내고 화면을 닫는 코드를 작성할 것이다.
package io.swnomad.sampleactivity;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MenuActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
Button button = findViewById(R.id.button); //레이아웃의 버튼 객체 참조
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(); // 인텐트 객체 생성
intent.putExtra("name", "mike"); //인텐트에 부가 데이터 추가
setResult(RESULT_OK, intent); //이 액티비티를 띄원 원래 액티비티로 응답 보내기
finish(); //액티비티 종료
}
});
}
}
버튼을 누르면 Intent 객체를 생성하고 여기에 부가적인 데이터를 넣는다. 부가데이터를 넣을 때에는 putExtra() 메소드를 사용하면 되는데, 데이터의 key-value 쌍을 함께 넣어야 한다. setResult 메소드는 원래의 액티비티로 응답을 보낼 때 사용하는 메소드인데, 응답코드와 인텐트 객체를 파라미터로 넣어준다. 응답코드 RESUlT_OK는 기본 API에 정의 된 상수로 -1이며, 정상 처리 되었음을 의미한다. 마지막으로는 finish() 메소드를 통해 화면을 닫는다.
이제 MainActivity.java 에서는 버튼을 클릭하면 MenuActivity를 띄우는 코드를 작성할 것이다. 먼저 activity_main.xml 파일에 버튼을 하나 추가한다.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
package io.swnomad.sampleactivity;
import android.content.Intent;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
public static final int REQUEST_CODE_MENU = 101; //액티비티를 띄우기 위한 요청코드 정의
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button2 = findViewById(R.id.button2);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), MenuActivity.class); //MenuActivity를 띄우기 위한 인텐트 객체 생성
startActivityForResult(intent, REQUEST_CODE_MENU); //액티비티 띄우기
}
});
}
/* AppCompatActivity 클래스에 정의된 onActivityResult() 메소드 재정의 */
/* onActivityResult() 메소드는 새로 띄운 액티비티가 보내온 응답을 처리하는 기능을 한다. */
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == REQUEST_CODE_MENU){ //MenuActivity를 띄울 때 사용했던 요청코드이면
Toast.makeText(getApplicationContext(),
"onActivityResult 메소드 호출됨. 요청코드 : " + requestCode + ", 결과코드 : " + resultCode,
Toast.LENGTH_LONG).show();
}
if(resultCode == RESULT_OK){ //응답 코드가 RESULT_OK 이면
String name = data.getExtras().getString("name"); // 부가 데이터의 값(value) 얻기
Toast.makeText(getApplicationContext(), "전달된 name : " + name, Toast.LENGTH_LONG).show();
}
}
}
startActivityForResult 메소드를 통해 액티비티를 띄우는데, 액티비티를 띄울 때 인텐트 객체가 사용되었다.인텐트 객체는 액티비티를 띄우거나 부가적인 데이터를 담아서 전송하는 등 여러가지 용도로 쓰이는 중요한 객체이다. 여기서는 액티비티를 띄운다는 것과 부가 데이터를 넣을 수 있다는 것만 알면 된다.
액티비티를 띄울 때 미리 정의한 요청코드를 함께 넣어주었다. 새로 띄운 액티비티에서 응답을 보내올 때, 방금 보낸 요청코드를 같이 보내온다. 이 요청코드를 보고 어떤 액티비티로부터 온 응답인지 알 수 있는 것이다. 요청코드의 값은 임의로 지정할 수 있지만 띄울 액티비티가 여러개인 경우 중복되지 않도록 설정해야 한다.
onActivityResult() 메소드는 액티비티로부터 오는 응답을 처리하는 역할을 한다. 이 메소드는 AppCompatActivity 클래스에 정의된 메소드를 재정의한 것이다. 첫 번째 전달인자인 requestCode를 읽어서 어떤 액티비티로 온 응답인지 확인할 수 있다. 그리고 resultCode를 확인하여 띄운 액티비티에서 처리한 결과의 정상 유무를 알 수 있다. 세 번째 전달인자인 인텐트 객체에서 부가데이터를 읽을 수 있다. 부가데이터가 없는 경우가 있을 수 있으므로 이 전달인자는 @Nullable 이 앞에 붙었다.
요청코드가 MenuActivity를 띄울 때 사용한 코드라면 요청코드와 결과코드를 확인하는 토스트 메시지를 하나 띄운다. 그리고 응답코드가 정상이라면 부가 데이터를 토스트 메시지로 띄운다. 부가 데이터의 값을 가져올 때는 key-value 쌍의 key를 사용한다.
'안드로이드' 카테고리의 다른 글
(안드로이드) 17 - 부가 데이터 (0) | 2020.05.18 |
---|---|
(안드로이드) 16 - 인텐트(Intent) (0) | 2020.05.18 |
(안드로이드) 14 - 인플레이션(Inflation) (0) | 2020.05.18 |
(안드로이드) 13 - 기본 위젯(3) - 입력상자(EditText) (0) | 2020.05.18 |
(안드로이드) 12 - 기본 위젯(2) - 버튼(Button) (0) | 2020.05.18 |