Android (안드로이드)

[Android] Intent 인텐트 (1) - 액티비티 전환 / 액티비티 이동 / 명시적 인텐트 / 액티비티 전환 생명주기

Oscar:) 2022. 8. 23. 17:59

지난 포스팅에서 앱의 4대 컴포넌트에 대해 공부했었다.

 

그리고 각각의 컴포넌트는 인텐트를 통해 통신한다.

(액티비티 시작, 서비스 시작, 브로드캐스트 전달 등)

 

 

이번 포스팅에서는 인텐트에 대해 알아보자.

 

 


인텐트 (Intent)

 

공식 문서에서는 인텐트를 다음과 같이 설명한다.

 

'인텐트는 메시징 객체로서, 다른 앱 구성 요소로부터 작업을 요청하는 데 사용한다'

 

위에서 언급했듯, 인텐트는 컴포넌트의 통신을 담당해준다.

 


 

인텐트는 사용 방법에 따라 두가지 유형으로 나눌 수 있다.

 

  • 명시적 인텐트

명시적 인텐트는 인텐트를 충족하는 구성 요소를 직접 지정한다.

이를 위해 해당 요소의 이름을 제공해야 한다. (패키지, 클래스 등)

일반적으로 앱 안에서 구성 요소를 시작할 때 사용한다. (액티비티, 서비스 등)

 

 

  • 암시적 인텐트

암시적 인텐트는 특정 구성 요소를 직접 지정하지 않지만,

수행할 작업을 선언하여 다른 앱의 구성 요소가 이를 처리할 수 있도록 해준다.

 

 

이번 포스팅에서는 명시적 인텐트에 대해서만 다룰 것이다.

 

암시적 인텐트는 조금 더 심화된 내용을 공부하게 되었을 때,

해당 포스팅에서 다뤄보겠다.

 


위에서 언급했듯이, 인텐트는 앱의 구성 요소와 통신하게 해주며

우리는 그 중 액티비티 전환에서 사용해볼 수 있다.

 

액티비티의 전환이란, 화면 전환을 뜻한다고 볼 수 있다.

 

 

두 개의 액티비티를 생성하여 액티비티 전환을 구현해보자.

 

MainActivity.java  -  activity_main.xml (이하 A액티비티)

SecondActivity.java  -  activity_second.xml (이하 B액티비티)

 


1. 먼저, 레이아웃에 버튼을 생성해주고

java 파일에서 버튼 객체를 참조해준다.

 

 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="이곳은 A 액티비티입니다."
        android:textSize="25dp"
        android:textColor="#0000ff"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.496"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.361" />

    <Button
        android:id="@+id/change_Btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="이 동"
        android:textSize="20dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.695" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

MainActivity.java

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        Button button = findViewById(R.id.change_Btn);
    }
}

 

+추가적으로, 위 코드에는 작성하지 않았지만

이전 Log 포스팅처럼 생명주기 메서드를 모두 작성해주자.

 


2. button 객체에 onClick 이벤트 리스너를 호출해주고,

해당 onClick 메서드 안에 인텐트를 작성해주자.

 

*이벤트 리스너에 대한 내용은 다른 포스팅에서 다뤄보겠다.

 

 

인텐트를 통해 액티비티 전환할 때의 문법은 다음과 같다.

                Intent i = new Intent(MainActivity.this,SecondActivity.class);
                startActivity(i);

 

 

인텐트 생성자 Intent() 의 괄호 안에는 다음과 같은 값을 작성한다.

 

첫 번째 인자 : 액티비티 클래스를 구현하는 context

두 번째 인자 : 호출할 액티비티 클래스

 

 

MainActivity.java 완성

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    String TAG = "메인 액티비티";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d(TAG, "onCreate() 호출됨");

        Button button = findViewById(R.id.change_Btn);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent i = new Intent(MainActivity.this,SecondActivity.class);
                startActivity(i);
            }
        });

    }

// 이하 생명주기 확인용 메서드 생략

}

 


3. 이제 B 액티비티를 생성해준다.

내용은 A 액티비티와 유사하다.

A 액티비티로 되돌아갈 버튼을 추가해준다.

 

activity_second.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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=".SecondActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="이곳은 B 액티비티입니다."
        android:textSize="25dp"
        android:textColor="#ff0000"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.496"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.361" />

    <Button
        android:id="@+id/back_Btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="뒤로가기"
        android:textSize="20dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.695" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

SecondActivity.java

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

public class SecondActivity extends AppCompatActivity {

    String TAG = "두번째 액티비티";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        Log.d(TAG, "onCreate() 호출됨");

        Button button = findViewById(R.id.back_Btn);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent i = new Intent(SecondActivity.this, MainActivity.class);
                startActivity(i);
            }
        });
    }

// 이하 생명주기 확인용 메서드 생략

}

 


4. 에뮬레이터로 앱을 실행해보자.

앱 실행 모습

 

A액티비티에 있는 '이동' 버튼을 클릭하면

B 액티비티로 전환된 모습

 

B 액티비티로 전환된 모습을 확인할 수 있다.

 


 

여기서 우리가 유심히 봐야될 부분은 생명주기 Log 이다.

 

A 액티비티에서 B 액티비티로 전환될 때.

 

A 액티비티가 onPause() 상태가 되고,

B 액티비티가 onCreate() > onStart() > onResume() 상태가 된 이후에

A 액티비티가 onStop() 되는 것을 확인할 수 있다.

 

위처럼, onPause() 와 onStop()이 적용되는 시기는 명확히 구분된다.

 

따라서 액티비티간 이동이 이루어질 때,

해당 생명주기 메서드의 용도를 명확히 구분하여 사용해야 한다.

 

비슷한 '정지' 라는 개념의 생명주기가 2개씩이나 있는 이유일 것이다.

 


 


5. 액티비티 전환을 여러번 거친 후,

기기의 ◀ 버튼을 통해 뒤로가기를 실행해보자.

 

액티비티가 쌓이는 모습

 

앱 밖으로 한 번에 나가지지 않고,

이동된 액티비티를 모두 거치는 모습을 확인할 수 있다.

 

startActivity() 를 통해 액티비티가 계속 생성되었기 때문이다.

 

만약 이 앱에서 메인 액티비티를 기준으로 정한다면,

이외의 액티비티가 계속 쌓인 채로 유지되는 것은 불필요하다.

 

 

SecondActivity 에서 뒤로가기 버튼을 클릭했을 때,

6. B 액티비티를 종료시켜줘야 한다는 사실을 알 수 있다.

 

SecondActivity.java 파일을 수정해주자.

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
//                Intent i = new Intent(SecondActivity.this, MainActivity.class);
//                startActivity(i);
                finish();
            }
        });

 

 

마찬가지로, 액티비티 전환을 여러번 거친 후에

기기의 ◀ 버튼을 통해 뒤로가기를 실행해보자.

한 번에 액티비티 밖으로 나간 모습

 

finish() 메서드를 통해

B 액티비티에서 버튼을 누르면 B 액티비티를 종료시켰고,

 

기기의 ◀ 버튼을 통해 한 번에 앱 밖으로 나가진 것을 확인할 수 있다.

 

 

 


 

 

이번 포스팅에서는 인텐트를 통해 액티비티를 전환해 보았다.

 

이제 여러개의 액티비티를 만들고,

다양한 화면이 구성된 앱을 만들 수 있게 되었다.