본문 바로가기
Android

Android Studio, java] 액티비티 변경하기, 데이터 이동하기

by 김마리님 2020. 7. 21.

한 프로젝트 내에서 MainActivity -> 다른 액티비티로 넘어가는 동작을 만들어본다.

먼저, 프로젝트 내의 화면을 만든다. 이 때, 코드 복붙 하지말고 다음과 같이 만들어야 화면 레이아웃도 함께 파일이 만들어진다.

 

이제 두 화면에 간단하게 화면이 구분이 될 정도만 디자인을 부여한다.

(혹시나 모르니 화면 코드)

더보기

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    android:background="@android:color/holo_blue_bright"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="9"
        android:textSize="25sp"
        android:text="메인 액티비티"
        android:gravity="center"/>

    <Button
        android:id="@+id/btn_move_sub"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:text="서브로 이동"/>

</LinearLayout>

 

activity_sub.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    android:background="@android:color/holo_orange_light"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="9"
        android:textSize="25sp"
        android:text="서브 액티비티"
        android:gravity="center"/>

    <Button
        android:id="@+id/btn_finish_sub"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:text="Sub종료"/>

</LinearLayout>

 

이제 코드를 설정해보자.

이벤트를 통해 변경한다(버튼을 클릭했을 때 이동)

 

MainActivity.java

package com.mary.activityex01;

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 {
    private static final String TAG = "Main_Activity";
    private Button btnMoveSub;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnMoveSub=findViewById(R.id.btn_move_sub);

        btnMoveSub.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(MainActivity.this, SubActivity.class);
                Log.d(TAG, "onClick: "+MainActivity.this);
                startActivity(intent);

            }
        });
    }
}

 

Intent 객체로 이동을 할 수 있다.

이 때, new를 할 때, 내 현재 액티비티 -> 내가 도착할 액티비티를 매개변수로 넣는다.

 

그리고 startActivity만 하면 이동할 수 있다.

 

그리고, sub에서 메인으로 다시 이동하는 방식이 두 가지가 있다.

안드로이드는 액티비티를 이동할 때, 사실 이전 액티비티를 삭제하는 것이 아니다.

이렇게 화면을 겹쳐서 만드는 거기 때문에(이 방식을 Task를 쌓는다고 한다), 돌아갈 때는 두 가지 방식이 있다.

1. 새 화면을 다시 올리기

2. 현재 화면을 종료하기

 

Task를 다시 쌓는 것은 프로그램의 성능이 낮아질 수 있기 때문에 이전 화면을 삭제하고 메인으로 돌아가는 것이 좋다.

 

SubActivity.java

package com.mary.activityex01;

import androidx.annotation.LongDef;
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 SubActivity extends AppCompatActivity {
    private static final String TAG = "SubActivity";

    private Button btnFinishSub;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sub);

        Intent intent=getIntent();

        btnFinishSub.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }
}

화면을 받아오는 건 getIntent만 하면 되고, 버튼을 클릭했을 때 화면을 삭제하는 방식은 단지 finish만 하면 된다.

 

결과 화면 :

 

이제 액티비티에서 액티비티로 데이터를 가져가보자.

먼저 간단하게 String 값을 들고 이동해보자.

 

1. 단일 값 들고 이동해보기.

 

- MainActivity.java

package com.mary.activityex01;

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 {
    private static final String TAG = "Main_Activity";
    private Button btnMoveSub;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnMoveSub=findViewById(R.id.btn_move_sub);

        btnMoveSub.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(MainActivity.this, SubActivity.class);
                Log.d(TAG, "onClick: "+MainActivity.this);
                intent.putExtra("name","mary");
                startActivity(intent);

            }
        });
    }
}

putExtra() 함수를 통해 내가 이후에 호출할 이름과 이름 내의 값을 지정하면 간단히 끝난다.

이 값을 화면전환 했을 때, 콘솔에 도출시켜보자.

 

- SubActivity.java

package com.mary.activityex01;

import androidx.annotation.LongDef;
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 SubActivity extends AppCompatActivity {
    private static final String TAG = "SubActivity";

    private Button btnFinishSub;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sub);

        Intent intent=getIntent();
 	String name=intent.getStringExtra("name");
        Log.d(TAG, "onCreate: "+name);

        btnFinishSub=findViewById(R.id.btn_finish_sub);

        btnFinishSub.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }
}

 

 

2. Object 값 가져가기.

그런데 putExtra의 문제가 있다.

putExtra는 Object를 지원하지 않는다.

이 때 이용하는 것이 bundle인데, 출발지에서 도착지로 이동하는 택배정도로 생각하면 된다.

또, 데이터의 직렬화 때문에 모델도 따로 만들어야 한다.

직렬화가 간단히 말하면 흩어진 데이터를 참고하게 좋게끔 배열로 만들어 전송하여 전송을 용이하게 하는 형태이다.

((직렬화에 대한 글))

https://rockdrumy.tistory.com/1044

 

[안드로이드] Activity에 대해서 - 객체 직렬화편(Serializable)

4. 객체 직렬화에 대해서 사실 순수하게는 Activity와 객체 직렬화는 다른 얘기이다. 그런데 왜 꼭 이 장에서 객체 직렬화에 대해서 다루고 있는 것일까? 앞으로 배우게 될 각 components 와 components 간

rockdrumy.tistory.com

우리가 직렬화할 모델은 Serializable 클래스를 상속시킨다.

 

- User.java

package com.mary.activityex01;

import java.io.Serializable;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder

public class User implements Serializable {
    private int id;
    private String username;
    private String password;
}

 

이제 이 값을 전송시켜보자.

 

- MainActivity.java

package com.mary.activityex01;

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 {
    private static final String TAG = "Main_Activity";
    private Button btnMoveSub;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnMoveSub=findViewById(R.id.btn_move_sub);

        btnMoveSub.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(MainActivity.this, SubActivity.class);
                Log.d(TAG, "onClick: "+MainActivity.this);
                Bundle bundle=new Bundle();
                bundle.putSerializable("user", new User(1, "ssar","1234") );
                intent.putExtras(bundle);
                startActivity(intent);

            }
        });
    }
}

먼저, 내가 가져갈 상자(Bundle)을 제작하고, 제작할 상자에 들어갈 데이터를 직렬화 한다(putSerializable).

그리고 그 값을 putExtras로, 단일값처럼 Intent에 넣어서 이동시킨다.

 

- SubActivity.java

package com.mary.activityex01;

import androidx.annotation.LongDef;
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 SubActivity extends AppCompatActivity {
    private static final String TAG = "SubActivity";

    private Button btnFinishSub;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sub);

        Intent intent=getIntent();
        User name=(User)intent.getSerializableExtra("user");
        Log.d(TAG, "onCreate: "+name.getId());
        Log.d(TAG, "onCreate: "+name.getUsername());

        btnFinishSub=findViewById(R.id.btn_finish_sub);

        btnFinishSub.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }
}

 

단. 여기서 참조할때는 직렬화했던 클래스를 참조하여 역직렬화를 해주어야(getSerializableExtra) 참조가 가능하다. 이 때, 상자에 든 것이 무엇을 참조해 직렬화했는지 알 수 없으므로 다운캐스팅 해주는 것도 잊지 말자.

 

 

반응형