본문 바로가기

Blog/Android

Parcelable 2, 여러 데이터 한번에 전달

메뉴 액티비티 추가할거니까 액티비티 추가(manifest.xml)

 

 

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/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            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>

 

 

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/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            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>

 

 

SimpleData.java

    import android.os.Parcel;
    import android.os.Parcelable;
    //새로운 클래스 하나 정의하고 그 클래스를 파슬러블이라는 인터페이스를 구현하도록 만들 것
    //Parcel이 결국에는 데이터를, 이 객체 안에 있는 데이터를 다른 데 전달할 때 사용되는 객체라고 생각하면 됨

    public class SimpleData implements Parcelable {//새로운 클래스를 정의하는 그리고 그게 파슬러블이라고 하는 인터페이스를 구현한다.
        int number;
        String message;

        public SimpleData(int number, String message) {//기본 생성자
            this.number = number;
            this.message = message;
        }

        public SimpleData(Parcel src){//생성자, 다른 Parcel 객체를 받았을 때, 이 Parcel이라고 하는 게 결국에는 데이터가 동일하다는 뜻?
            number = src.readInt();//Integer 타입의 데이터를 하나 읽어서 number라는 변수에 할당을 하겠다.
            message = src.readString();
        }
        //다른 Parcelable이라는게 만들어지면 그걸 파라미터로 받을 수가 있는데, 파라미터로 받으면 Simple data안에 있는
        //두 개의 변수값을 read해서 할당을 하겠다.(내 생각 : 하나의 객체에서 다른 하나의 객체로 옮기기?)
        //Parcel에서 SimpleData 안에 들어가 있는 변수를 read로 복원하는 거

        //CREATOR라고 하는 필드가 있어야 함(크리에이터 타입)
        public static final Parcelable.Creator CREATOR = new Parcelable.Creator(){//크리에이터 이용해 새로운 객체 만들어줌
            //여기에 필요한 메서드 추가해야 함
            public SimpleData createFromParcel(Parcel src){//즉 이 메소드를 호출하면 SimpleData(Parcel src)라는 생성자 호출해서 그 Parcel에서 두 개 읽어서
                return new SimpleData(src);                //여기에 변수 할당하는 거
            }
            public SimpleData[] newArray(int size){//전달된 사이즈 수에 맞게 SimpleData라는 객체의 새로운 배열을 생성
                return new SimpleData[size];
            }
        };//이게 크리에이터라고 하는 객체고 Parcelable이라고 하는 걸 implement, 구현하게 되면 이런 형태의 Creator 변수를 하나 선언해주게 됨
        //이 안에 들어있는 메소드가 필수!


        //인터페이스 구현을 위한 기본적 메소드
        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {//Parcel 객체로 써준다는 얘기, SimpleData라고 하는 게 Parcel이라고 하는 걸로 바뀐다고 볼 수 있음
            dest.writeInt(number);
            dest.writeString(message);

        }
    }//SimpleData를 Parcel로 바꿔주는 거

    //중요한 건 우리가 SimpleData라고 하는 클래스를 정의했고, 이 SimpleData를 이용해서 새로운 객체를 만들 수 있는데
    //그 객체가 Parcelable이라고 하는 인터페이스를 구현하고 있다는 거
    //그래서 이걸 가지고

Parcelable 인터페이스를 받아서 클래스를 만듦, 그 클래스의 객체를 전달하기 위함

 

 

MainActivity.java

    import android.content.Intent;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;

    import java.util.ArrayList;

    public class MainActivity extends AppCompatActivity {
        Button button;

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

            button =  (Button)findViewById(R.id.button);
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(getApplicationContext(), MenuActivity.class);

    //                ArrayList<String> names = new ArrayList<String>();
    //                names.add("김진수");
    //                names.add("황수연");
    //                intent.putExtra("names", names);

                    SimpleData data = new SimpleData(100, "Hello");
                    intent.putExtra("data", data);//원래 기본적으로는 객체를 바로 넣을 수 없는데, 이렇게 Parcelable을 구현한 클래스를 만들고
                    //거기서 그 클래스를 이용해서 만든 객체인 경우엔 이렇게 넣을 수 있다는 것
                    //마찬가지로 저 데이터를 받아서 사용할 수 있음



                    startActivityForResult(intent, 101);
                }
            });
        }
    }

 

 

 

MenuActivity.java

    import android.content.Intent;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.support.v7.widget.AppCompatButton;
    import android.view.View;
    import android.widget.Button;
    import android.widget.Toast;

    import java.util.ArrayList;

    public class MenuActivity extends AppCompatActivity {
        Button button2;

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

            button2 = (Button)findViewById(R.id.button2);
            button2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    finish();
                }
            });

            //이걸 메뉴 액티비티가서 전달받은 데이터를 뽑아야 할 텐테 메뉴 액티비티라고 하는 게 새로 뜨게 되면 onCreate가 처음에 호출됨
            //그래서 이 안에서 전달된 인텐트를 확인하고 싶다고 하면 getIntent()하면 됨
            Intent passedIntent = getIntent();//이렇게 하면 메인 액티비티에서 전달된 인텐트 여기로 오는 거
            processIntent(passedIntent);//processIntent 메서드를 이용해 passedIntent를 전달해 처리
        }

        private void processIntent(Intent passedIntent){
            if(passedIntent != null){//가져온 인텐트가 널이 아니면
    //            ArrayList<String> names = (ArrayList<String>)passedIntent.getSerializableExtra("names");//인텐트 내용을 뽑아볼건데, 자 어레이리스트를 바로 넣을 수 있는 가장 기본적인 이유는
    //            //어레이 리스트가 자바 api 기본으로 들어가 있는데 그게 serializable 인터페이스를 구현하기 때문(implement하기 때문)
    //            //그래서 serializable을 집어넣고 뺄 수 있음
    //            if(names != null){
    //                Toast.makeText(getApplicationContext(), "전달받은 이름 리스트 갯수 : " + names.size(), Toast.LENGTH_LONG).show();
    //            }

                SimpleData data = (SimpleData)passedIntent.getParcelableExtra("data");
                if(data != null){
                    Toast.makeText(getApplicationContext(), "전달받은 SimpleData : " + data.number + ", " + data.message , Toast.LENGTH_LONG).show();
                }
            }
        }
    }
    //Parcelable을 권장한다고 했는데 Parcelable을 사용하지는 않지만 실제로는 많이 사용함, 왜냐면 파슬러블 별도로 정의하려고 하면 꽤 번거로움
    //그러다 보니 기존에 있는 거를 그대로 쓰기도 하고, 어레이리스트는 자바에서 상당히 많이 쓰는데 여러 개 의 데이터를 관리할 때 특히나
    //우리가 할 리스트 뷰라고 하는 데 안에다가 데이터로 어레이리스트를 집어넣는 경우가 많은데 데이터가 필요할 때 데이터를 바로바로 액티비티 화면과
    //화면 사이에 또는 서비스에서 화면을 띄울 때 어레이리스트를 바로 전달해서 보여줄 수 잇는 장점이 있음
    //그래서 위 방법 어레이리스트도 실제로 많이 사용된다.
    //인텐트 안에 부가 데이터를 넣을 때 위 같은 방식으로 serializable이라고 하는 거를 implement, 구현한 거는 우리가 직접 클래스를 만들고
    //시리얼라이저블 구현하는 것도 바로 부가데이터에 넣어서 바로 뽑을 수 있다.