안드로이드 애플리케이션에는 4대 기본 구성요소가 있다.

1

앱을 안드로이드 디바이스에 설치하면 시스템은 위 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 메소드를 통해 액티비티를 띄우는데, 액티비티를 띄울 때 인텐트 객체가 사용되었다.인텐트 객체는 액티비티를 띄우거나 부가적인 데이터를 담아서 전송하는 등 여러가지 용도로 쓰이는 중요한 객체이다. 여기서는 액티비티를 띄운다는 것과 부가 데이터를 넣을 수 있다는 것만 알면 된다.

액티비티를 띄울 때 미리 정의한 요청코드를 함께 넣어주었다. 새로 띄운 액티비티에서 응답을 보내올 때, 방금 보낸 요청코드를 같이 보내온다. 이 요청코드를 보고 어떤 액티비티로부터 온 응답인지 알 수 있는 것이다. 요청코드의 값은 임의로 지정할 수 있지만 띄울 액티비티가 여러개인 경우 중복되지 않도록 설정해야 한다.

2

onActivityResult() 메소드는 액티비티로부터 오는 응답을 처리하는 역할을 한다. 이 메소드는 AppCompatActivity 클래스에 정의된 메소드를 재정의한 것이다. 첫 번째 전달인자인 requestCode를 읽어서 어떤 액티비티로 온 응답인지 확인할 수 있다. 그리고 resultCode를 확인하여 띄운 액티비티에서 처리한 결과의 정상 유무를 알 수 있다. 세 번째 전달인자인 인텐트 객체에서 부가데이터를 읽을 수 있다. 부가데이터가 없는 경우가 있을 수 있으므로 이 전달인자는 @Nullable 이 앞에 붙었다.

요청코드가 MenuActivity를 띄울 때 사용한 코드라면 요청코드와 결과코드를 확인하는 토스트 메시지를 하나 띄운다. 그리고 응답코드가 정상이라면 부가 데이터를 토스트 메시지로 띄운다. 부가 데이터의 값을 가져올 때는 key-value 쌍의 key를 사용한다.

3
4
5

+ Recent posts