Activity2

Du-Hyeon, Kim·2023년 8월 31일
0

Android

목록 보기
8/12

Activity2

화면을 아애 전환하고,
그 전환 간에 데이터 전송하는 방법

Activity 전환(intent)

1.getApplicationContext

버튼이 포함되 있는 주변 정보
버튼이 어떤 layout에 포함되어있는가,
버튼의 환경정보,
ui 객체는 무조건 context객체를 전달받게 되어 있음

2. intent로 화면 전환1

main -> menu로의 화면 전환

Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(getApplicationContext(), MenuActivity.class);
                //menu activity를 지정하는 intent 객체를 만든 것
                //menu activity는 class객체를 지정함???
                startActivityForResult(intent, 101);
                //101 : 나중에 새로 띄운 화면으로 응답을 받을 대 그대로 돌아옴
                //어떤 화면에서부터 요청받은지를 구분 할 수 있다.

            }

3. intent로 화면전환2

menu -> main으로 "mike"라는 데이터 가지고 전환

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

        Button button = findViewById(R.id.button2);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent();
                intent.putExtra("name", "mike");
                setResult(RESULT_OK, intent);
                //돌아갈때, 200코드가 전달됨 = RESULT_OK

                finish();
            }
        });

4. intent.putExtra();

name - value를 짝지어서 전송가능

5. intent 데이터 받기

화면 전환시 전송된 Extra데이터를 intent를 이용하여 받는다

menu activity에서

setResult(RESULT_OK, intent);

로 intent 데이터를 전송했다.

이때, mainActivity에서

@Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        //101, 200(RESULT_OK), intent 가 전달됨
        super.onActivityResult(requestCode, resultCode, data);

        if(requestCode == 101){
            if(data != null){
                String name = data.getStringExtra("name");
                if(name != null){
                    Toast.makeText(this,"응답으로 받은 name : " + name, Toast.LENGTH_LONG).show();
                    //this : activity = context or getApplicationContext
                }
            }

        }
    }

6. onActivityResult()

기존 method를 override함

7. intent

화면 있는 것 : activity
화면 없는 것 : service
메세지를 전달 할 수 있는거 : broadcast

app 구성요소가 데이터를 전달하는게 intent로 가능함

CallInetnt

1. Intent.ACTION_VIEW


public void onClick(View view) {
                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("tel:010-6654-9551"));
                startActivity(intent);
                //System에 요청, android os activity manager가 전화번호를 보고 activity를 띄움
            }

2. intent 해석

System이 이해할 수 있게 만든 객체 = intent
system이 이해할 수 있는 정보들로 구성됨
ACTION, data = 를 보고 os가 해석함

3. 이전 menu activity 호출 재정의

intent를 띄우는 다른 방식

Intent intent = new Intent();
                //component는 activity를 가리키기 위해서도 사용가능하다.
                ComponentName name = new ComponentName("org.techtown.CallIntent", "org.techtown.CallIntent.MenuActivity");
                intent.setClass(name);
                startActivityForResult(intent, 101);

Inetent 내용정리

1. 요청process 사진


출처: https://www.youtube.com/watch?v=7M-mG4xcANk

startActivityforResult : 응답까지 받고 싶은 경우
startActivity : 응답 필요 없음


띄워진 activity에서 finish를 하게 되면 이전 activity로 돌아옴
이때,
setResult()를 통해 intetn에 데이터를 넣어서 전송가능하다.

2. app 구성요소간 intent를 활용해 실행가능

3. 엑티비티 스택

stack에 쌓아지는다고 보는 것과 비슷하다.
화면이 여러개 쌓임
이때,
동일한 activity를 쌓은상황은 어떻게 하나?

intent flag
를 사용해서 두개의 중첩된 동일한 activity가 띄지 않게함

4. 번들(bundle)

putExtra와 getStringExtra는
intent안에 bubdle에 넣었다 뺐다하는 것임

Parcelable 예제

클래스를 넣었다가 뺼 수 있도록하는 경우
부가데이터에 클래스를 넣음

1.Parcelable 객체 생성의 의의

read와 write
최대한 내가 원하는 데이터만 만들어서 전송하면
적은 메모리를 먹음

2. SimpleData class 작성

activity파일이 들어있는 dirctory에
SimpleData.java파일을 만들고
SimpleData class를 정의한다.

package org.techtown.parcelable;

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

import androidx.annotation.NonNull;

import com.google.android.material.internal.ParcelableSparseArray;

public class SimpleData implements Parcelable {
    int code;
    String message;

    public SimpleData(int code ,String message){
        this.code = code;
        this.message = message;
    }

    public SimpleData(Parcel src){
        code = src.readInt();
        message = src.readString();
    }

    public static final Parcelable.Creator CREATOR = new Parcelable.Creator(){
        public SimpleData createFromParcel(Parcel in){
            return new SimpleData(in);
        }

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

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

    @Override
    public void writeToParcel(@NonNull Parcel parcel, int i) {
        parcel.writeInt(code);
        parcel.writeString(message);
    }
}

3. SimpleData class 해석

Parcelable 상속

public class SimpleData implements Parcelable

기본 정보

int형 code + string형 message를 가지는 클래스
타입에 따라 초기화를 다르게 진행하여 code와 message 저장

public SimpleData(int code ,String message){
        this.code = code;
        this.message = message;
    }

public SimpleData(Parcel src){
        code = src.readInt();
        message = src.readString();
    }

이 부분은 아직 이해가 안됨

Parcelable 형태로 만들기 위한 코드다.
일단 Parcle 객체라는 것을 이해를 좀 더 해봐야 할 것 같다.

public static final Parcelable.Creator CREATOR = new Parcelable.Creator(){
        public SimpleData createFromParcel(Parcel in){
            return new SimpleData(in);
        }

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

parcel 안에 있는 것을 활용해서 만들겠다?

Parcelable 필수 methods(override)

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

    @Override
    public void writeToParcel(@NonNull Parcel parcel, int i) {
        parcel.writeInt(code);
        parcel.writeString(message);
    }

4. SimpleData로 데이터 저장하기

main activity에서 button누르면 호출하고,
화면 전환

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 data = new SimpleData(200, "OK");
                intent.putExtra("data", data);
                startActivity(intent);
            }
        });

intent에 putExtra로 넣는 데이터가 simpleData형식을 취함

SimpleData data = new SimpleData(200, "OK");
intent.putExtra("data", data);

simpledata인 data를 intent에 넣어서 menu activity로 result없는 activity 전환을 함

최종 결과(class data 전송과 읽기 + toast message)

5. intent에서 data(simpledat) 처리하기

main에서 menu로 전달한
intent에서 data를 꺼내고,
그것을 precess하는 과정

Intent intent = getIntent();
processIntent(intent);

processIntent함수
intent안에 저장된 code와 message는 bundle형태로 저장되어 있으니,
그것을 key을 활용해서 simpleData형의 변수에 다시 저장하고,
toast message를 띄운다.

public void processIntent(Intent intent){
        if(intent != null){
            Bundle bundle = intent.getExtras();
            SimpleData data = bundle.getParcelable("data");
            if(data != null){
                Toast.makeText(this, "전달 받은 객체 정보 : " + data.code + ", "+ data.message, Toast.LENGTH_LONG).show();

            }
        }
    }

Task

꼭 하나의 앱인 것처럼 보여주는 것
activity가 자연스럽게 넘어감

수명주기

1.상태별 Log.d 출력

activity의 상태를 감지하는 종류는 아래와 같다.
onCreate
onStop
onDestory
onStart
onPostResume
이것을
activity java에서 override해서 log를 띄워보면 아래와 같이 출력된다.

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

        Log.d("Main", "onCreate 호출됨");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("Main", "onDestroy 호출됨");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.d("Main", "onStop 호출됨");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.d("Main", "onStart 호출됨");
    }

    @Override
    protected void onPostResume() {
        super.onPostResume();
        Log.d("Main", "onPostResume 호출됨");

    }

위의 5가지 경우
logchat으로 활동을 확인해 보면 다음과 같이 log가 출력된다.
또한 전화가 갑자기 걸려오거나 하는 상황에서는 onPause가 출력될 것이다.


2. pause에서 데이터 저장하기

따라서 onPause에서 데이터 저장
onResume에서 다시 불러오는 것으로 지정해야된다.
sharedPreferences로 데이터 저장가능

값을 화면을 껐다가 켜도 계속 유지됨

@Override
    protected void onStop() {
        super.onStop();
        Log.d("Main", "onStop 호출됨");
        saveState();
    }

@Override
    protected void onPostResume() {
        super.onPostResume();
        Log.d("Main", "onPostResume 호출됨");
        loadState();

    }


public void saveState(){
        SharedPreferences pref = getSharedPreferences("pref", Activity.MODE_PRIVATE);
        SharedPreferences.Editor editor = pref.edit();
        editor.putString("name", editText.getText().toString());
        editor.commit();
    }

    public void loadState(){
        SharedPreferences pref = getSharedPreferences("pref", Activity.MODE_PRIVATE);
        if(pref != null){
            String name = pref.getString("name", "");
            editText.setText(name);
        }

    }

onStop에서 save
onResume에서 load한다.

0개의 댓글