모바일/안드로이드앱

안드로이드 앱 intent 객체생성, 부가데이터, 인터페이스로 데이터 값 전달하기 / Android Studio / 안드로이드 앱만들기 23

yy_dd2 2021. 3. 12. 21:43
반응형

부가데이터

 

- 부가 데이터는 번들 객체 안에 넣은 데이터다

- 부가데이터는 시스템에서 건드리지 않고 다른 앱요소로 전달

- 액티비티 띄울 때 전달되는 인텐트 안에 부가 데이터(Extra data)를 넣어서 전달한다

- 인텐트 안에 번들(Bundle) 객체가 있고 번들 객체는 putExtra()와 get...Extra() 메서드로 데이터를 넣거나 뺸다

- Bundle 안의 putExtra()는 문자열을 집어 넣고 싶을때 호출 / get...Extra()는 문자열을 빼내고 싶을때 (...은 자료형 타입)

- 기본 자료형(Primitive Data Type)도 가능하지만 바이트 배열이나 Serializable 객체도 집어 넣고 빼내고 가능

- 부가 데이터를 넣을 때는 키와 값으로 만들어 넣는다 Key Value

 

- 대표 메서드

Intent putExtra(String name, String value)

Intent putExtra(String name, int value)

Intent putExtra(String name, boolean value)

 

String getStringExtra(String name)

int getIntExtra(String name, int defaultValue)

boolean getBooleanExtra(String name, boolean defaultValue)

 

 

- get...() 형태 메서드는 데이터의 값이 없으면 default로 설정한 defaultValue 값이 반환된다

- 기본자료형이 아닌 객체(Object) 자료형인 경우 객체 자체를 전달할수 없다 그래서 바이트 배열로 변환하거나 Serializable 인터페이스 구현하는 객체를 만들어 직렬화한 다음에 전달해야한다

- Serializable보다는 Parcelable 인터페이스를 권장하는데 이유는 직렬화하면 크기가 작아서 자주 사용한다

 

- Parcelable 인터페이스를 사용하면 객체를 번들에 직접 추가해야한다 두개의 메서드를 모두 구현해야함

public abstract int describeContents()

public abstract void writeToParcel(Parcel dest, int flags)

describeContnets() : 직렬화 하는 객체 유형을 구분

writeToParcel() : 객체가 가지고 있는 데이터를 Parcel 객체로 만들어준다 read...() 와 write...() 형태를 가진 메서드 제공

 


Parcel 인터페이스를 구현해 객체를 정의하고 객체를 인텐트에 넣어서 전달해보자

 

1. SampleParcelable 프로젝트 만들기

2. 텍스트뷰 삭제 버튼추가 메뉴띄우기

3. 새 액티비티 만들기 MenuActivity

 

4. 새 자바파일 class 만들기

- Parcelable 자료형으로 된 객체를 메뉴화면에 전달하려면 클래스를 재정의 해야한다

- class : SimpleData

- InterFace : Parcelable

** 안드로이드 스튜디오 업그레이드로 책과 화면이 달라져서 새 클래스 app-자바-자바패키지 에 우클릭 Create New Class 화면이 다르다

새 java class 파일(SimpleData)을 만들고 그안에 직접 인터페이스를 만들었다

처음에 만들면 public class SimpleData{} 만 있는데

public class SimpleData implements Parcelable {}

이렇게 추가하면 빨간전구가 있다 그걸 눌러서

Implement methods를 누른다

그럼 책에서 설명하는 android.os 패키지 안에 들어있는 추가할 메소드를 추가할수있다

그리고나면 이런 상태가되는데 SimpleData에 빨간줄이 쳐져있다

아직 추가되지 않은게 있나보다

package com.togapp.sampleparcelable;

import android.os.Parcel;
import android.os.Parcelable;

public class SimpleData implements Parcelable {
    
    protected SimpleData(Parcel in) {
    }

    public static final Creator<SimpleData> CREATOR = new Creator<SimpleData>() {
        @Override
        public SimpleData createFromParcel(Parcel in) {
            return new SimpleData(in);
        }

        @Override
        public SimpleData[] newArray(int size) {
            return new SimpleData[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
    }
}

 

만들어진 class 파일 코드

 

책에서는 SimpleData.java 파일에 Parcelable 인터페이스 구현 코드추가 하는게 먼저나오는데

처음 코딩을 접하는 사람은 화면의 동작이 진행되는거부터 하는게 좋은거 같다

그래서 나는 버튼을 클릭하면 띄워지는 화면을 먼저 해야겠다. (class 파일부터 하면 읽어와야하는 파일을 작성하는 코드를 작성할때 오류가 난다 그래서 그부분이 지워지고 왜 적어야하는지 모르기 때문에 버튼을 누르고 -> 파일을 읽어오는 부분을 작성하는게 좋을거같다)

 

5. MainActivity.java 버튼 누르면 띄우는 화면 코드 작성

package com.togapp.sampleparcelable;

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 {

    public static final int REQUEST_CODE_MENU = 101;
    public static final String KEY_SIMPLE_DATA = "data";

    @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 view) {
                Intent intent = new Intent(getApplicationContext(), MenuActivity.class);
                // SimpleData 객체 생성
                SimpleData data = new SimpleData(100, "Helloo Android!");
                // 인텐트에 부가 데이터로 넣기
                intent.putExtra(KEY_SIMPLE_DATA, data);
                startActivityForResult(intent, REQUEST_CODE_MENU);
            }
        });
    }
}

 

6. SimpleData.java 인터페이스 구현 코드 작성

package com.togapp.sampleparcelable;

import android.os.Parcel;
import android.os.Parcelable;

public class SimpleData implements Parcelable {

    int number;
    String message;

    // Parcel 객체에서 읽기
    public SimpleData(Parcel in) {
        number = in.readInt();
        message = in.readString();
    }

    // CREATOR 상수 정의
    public static final Creator<SimpleData> CREATOR = new Creator<SimpleData>() {
        @Override
        public SimpleData createFromParcel(Parcel in) {
            // SimpleData 생성자 호출 Parcel 객체에서 읽기
            return new SimpleData(in);
        }

        @Override
        public SimpleData[] newArray(int size) {
            return new SimpleData[size];
        }
    };

    // MainActivity.java에서
    // SimpleData 객체 생성 할때
    // SimpleData data = new SimpleData(100, "Helloo Android!"); 이부분에서 필요한것
    public SimpleData(int num, String msg) {
        number = num;
        message = msg;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    // Parcel 객체로 쓰기
    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeInt(number);
        parcel.writeString(message);
    }
}

 

7. activity_menu.xml 화면구현

돌아가기 버튼과 전달받은 데이터가 보이도록 text 속성 설정

더보기
<?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=".MenuActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="전달받은 데이터"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <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_toBottomOf="@+id/textView" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

8. MenuActivity.java 전달받은 인텐트를 처리하는 코드 작성

package com.togapp.sampleparcelable;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MenuActivity extends AppCompatActivity {

    TextView textView;

    public static final String KEY_SIMPLE_DATA = "data";

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

        textView = findViewById(R.id.textView);
        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent();
                intent.putExtra("neme","mike");
                setResult(RESULT_OK, intent);

                finish();
            }
        });

        Intent intent = getIntent();
        processIntnet(intent);
    }

    private void processIntnet(Intent intent) {
        if (intent != null){
            Bundle bundle = intent.getExtras();
            SimpleData data = bundle.getParcelable(KEY_SIMPLE_DATA);
            if(intent != null){
                textView.setText("전달받은데이터\nNumber : " + data.number + "\nMessage : " + data.message);
            }

        }
    }

}

중간에 인터페이스가 있는데 자바를 배워도 안배워도 인터페이스 구현해서 거기에 집어넣고 전달해서 가져오고 하는건 어려운거 같다

제대로 이해할 필요가있다...

 

메인화면에서 화면의 띄우고 메뉴화면으로 데이터를 전달할것

1. 

- 메인화면에서 데이터를 전달하지만 인터페이스로 구현된 SimpleData안에 집어넣고 그걸 불러오는 것을 할것

- 인터페이스 SimpleData 구현

 

2.

- MainActivity 코드작성 버튼 누르면 액티비티(Menu) 띄우기

- Menu액티비티 띄울때 전달할 값 설정

- 메인화면의 MainActivity.java 파일에서 SimpleData 객체를 생성하고 인텐트안에 부가데이터 넣기

- 부가데이터는 키 벨류 값으로 KEY_SIMPLE_DATA = "data" 로 설정한 intent.putExtra(KEY_SIMPLE_DATA, data); 라고 작성 ===> 해석하면 intent.putExtra("data", data); ===>여기서값 data는 그전에만든

- ===>여기서 키와 벨류값 data는 그전에만든 객체 생성할때 만들었던 SimpleData data = new SimpleData(100, "Helloo Android!"); 의 100, "Helloo Android!" 이다

 

3. MenuActivity.java 파일에서 

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent();
                intent.putExtra("neme","mike");
                setResult(RESULT_OK, intent);

                finish();
            }
        });

이부분은 새로 띄운 화면을 닫으면 전달할 값을 인텐트에 저장한것이고

        Intent intent = getIntent();
        processIntnet(intent);
    }

아래 이부분에 processIntent(intnet); 이부분을 보면된다 값을 가져오는 코드다.

    private void processIntnet(Intent intent) {
        if (intent != null){
            Bundle bundle = intent.getExtras();
            SimpleData data = bundle.getParcelable(KEY_SIMPLE_DATA);
            if(intent != null){
                textView.setText("전달받은데이터\nNumber : " + data.number + "\nMessage : " + data.message);
            }

        }
    }

 

 

기억하기

 

인터페이스 구현하고 화면에서 객체를 생성하고 그안에 데이터를 넣고 인텐트안에 키벨류값으로 넣고

다른 액티비티를 띄울때 인텐트에 부가데이터로 집어넣은걸 불러오기

 

github.com/young-0112/SampleParcelable

반응형