Computer >> 컴퓨터 >  >> 프로그래밍 >> Android

Android 액티비티 간 대용량 데이터를 전달하는 방법 (Bundle·Serializable 예제)

이 글에서는 Android 액티비티(Activity) 간에 대용량 데이터를 전달하는 방법을 단계별 예제와 함께 살펴봅니다. 핵심은 Serializable 인터페이스를 구현한 객체를 Bundle에 담아 Intent로 전달하는 것입니다.

핵심 개념: Serializable과 Bundle

Intent의 putExtra()는 String이나 int 같은 기본 타입만 직접 지원합니다. 따라서 여러 필드를 가진 객체나 리스트를 통째로 전달하려면 데이터 클래스가 Serializable(또는 Parcelable)을 구현해야 합니다. 이 예제에서는 구현이 간단한 Serializable을 사용해 이름·나이·도시 정보를 담은 User 객체를 ArrayList로 감싸 다음 화면으로 넘깁니다. 참고로 데이터 양이 많거나 전송이 잦은 앱이라면 처리 속도가 더 빠른 Parcelable 사용을 고려하는 것이 좋습니다.

1단계 — 새 프로젝트 생성

Android Studio에서 File ⇒ New Project로 이동해 새 프로젝트를 생성하고, 필요한 모든 정보를 입력합니다.

2단계 — activity_main.xml 작성

res/layout/activity_main.xml에 아래 코드를 추가합니다. 이름(Name), 나이(Age), 도시(City)를 입력받는 EditText 3개와 화면을 전환하는 Button으로 구성되어 있습니다.

<?xml version = "1.0" encoding = "utf-8"?>
<LinearLayout xmlns:android = "https://schemas.android.com/apk/res/android"
    xmlns:tools = "https://schemas.android.com/tools"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    android:layout_margin = "16dp"
    android:orientation = "vertical"
    tools:context = ".MainActivity">
    <EditText
        android:id = "@+id/etName"
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content"
        android:layout_gravity = "center"
        android:hint = "Name"
        android:inputType = "textCapWords" />
    <EditText
        android:id = "@+id/etAge"
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content"
        android:layout_gravity = "center"
        android:hint = "Age"
        android:inputType = "number" />
    <EditText
        android:id = "@+id/etCity"
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content"
        android:layout_gravity = "center"
        android:hint = "City"
        android:inputType = "textCapWords" />
    <Button
        android:id = "@+id/button"
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content"
        android:layout_gravity = "center"
        android:layout_marginTop = "16dp"
        android:text = "Next" />
</LinearLayout>

3단계 — User.java 데이터 클래스 작성

전달할 데이터를 담을 User 클래스를 src/User.java로 생성하고 Serializable 인터페이스를 구현합니다. name, age, city 필드와 함께 getter/setter 메서드를 정의합니다.

package com.example.myapplication;
import java.io.Serializable;
public class User implements Serializable {
    private String city;
    private String name;
    private String age;
    User(String name, String age, String city) {
        super();
        this.name = name;
        this.age = age;
        this.city = city;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }
}

4단계 — MainActivity.java 작성

버튼을 클릭하면 세 개의 입력값을 읽어 User 객체로 만들고 ArrayList에 담은 뒤, Bundle.putSerializable()로 저장합니다. 그리고 이 Bundle을 Intent에 실어 SecondActivity를 시작합니다.

package com.example.myapplication;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    EditText etName, etAge, etCity;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        etName = findViewById(R.id.etName);
        etAge = findViewById(R.id.etAge);
        etCity = findViewById(R.id.etCity);
        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String name = etName.getText().toString().trim();
                String age = etAge.getText().toString().trim();
                String city = etCity.getText().toString().trim();
                ArrayList<User> userList = new ArrayList<>();
                userList.add(new User(name, age, city));
                Bundle bundle = new Bundle();
                bundle.putSerializable("myUser", userList);
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                intent.putExtras(bundle);
                startActivity(intent);
            }
        });
    }
}

5단계 — activity_second.xml 작성

res/layout/activity_second.xml에는 전달받은 데이터를 표시할 TextView 하나만 배치합니다.

<?xml version = "1.0" encoding = "utf-8"?>
<LinearLayout xmlns:android = "https://schemas.android.com/apk/res/android"
    xmlns:tools = "https://schemas.android.com/tools"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    android:layout_margin = "16dp"
    android:orientation = "vertical"
    tools:context = ".SecondActivity">
    <TextView
        android:id = "@+id/textView"
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content" />
</LinearLayout>

6단계 — SecondActivity.java 작성

getIntent().getExtras()로 Bundle을 꺼낸 뒤 getSerializable()을 호출해 ArrayList<User>로 캐스팅하고, 각 필드 값을 TextView에 출력합니다. null 체크를 통해 데이터가 없는 경우에도 앱이 안전하게 동작하도록 처리했습니다.

package com.example.myapplication;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import java.util.ArrayList;

public class SecondActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        Bundle bundle = getIntent().getExtras();
        if (bundle != null) {
            ArrayList<User> userList = (ArrayList<User>) bundle.getSerializable("myUser");
            if (userList != null) {
                String name = userList.get(0).getName();
                String age = userList.get(0).getAge();
                String city = userList.get(0).getCity();
                TextView tvName = findViewById(R.id.textView);
                String user = "Name: " + name + "\nAge: " + age + "\nCity: " + city;
                tvName.setText(user);
            }
        }
    }
}

7단계 — AndroidManifest.xml에 액티비티 등록

새로 만든 SecondActivity를 androidManifest.xml에 반드시 등록해야 합니다. 등록을 누락하면 화면 전환 시점에 앱이 강제 종료됩니다.

<?xml version = "1.0" encoding = "utf-8"?>
<manifest xmlns:android = "https://schemas.android.com/apk/res/android"
    package = "com.example.myapplication">
    <application
        android:allowBackup = "true"
        android:icon = "@mipmap/ic_launcher"
        android:label = "@string/app_name"
        android:roundIcon = "@mipmap/ic_launcher_round"
        android:supportsRtl = "true"
        android:theme = "@style/AppTheme">
        <activity android:name = ".MainActivity">
            <intent-filter>
                <action android:name = "android.intent.action.MAIN" />
                <category android:name = "android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name = ".SecondActivity"></activity>
    </application>
</manifest>

앱 실행 및 결과 확인

실제 안드로이드 기기가 컴퓨터에 연결되어 있다고 가정하고 앱을 실행해 보겠습니다. Android Studio에서 프로젝트의 액티비티 파일을 하나 연 뒤 툴바의 Run 아이콘을 클릭하고, 옵션 목록에서 연결된 모바일 기기를 선택하면 기기에 기본 화면이 표시됩니다.

이름, 나이, 도시를 입력하고 Next 버튼을 누르면 두 번째 화면에 입력한 사용자 정보가 그대로 출력되는 것을 확인할 수 있습니다. 이처럼 Serializable 객체를 Bundle에 담아 전달하면 기본 타입뿐 아니라 복잡한 데이터 구조도 액티비티 간에 손쉽게 주고받을 수 있습니다.