인텐트(intent)를 이용한 액티비티간 전환(화면 변경)

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

TextView textView = findViewById(R.id.hello_text);
textView.setText("안녕하세요");

findViewById(R.id.button).setOnClickListener( new View.OnClickListener() {
public void onClick(View view) {
Intent intent = new Intent(this, SubActivity.class); // 이동할 액티비티를 입력변수로 사용
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra("EXTRA_MESSAGE", message); // Key-Value 형태로 데이터 저장하기
startActivity(intent); // 액티비티 이동
}
});
[SubActivity]
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Intent intent = getIntent(); // 데이터 수신

// 변수 저장하기(From intent)
String message = intent.getExtras.getString("EXTRA_MESSAGE"); // 문자열
// intent.getExtras().getInt("EXTRA_MESSAGE"); // 숫자형
// intent.getExtras().getInt("EXTRA_MESSAGE"); // 숫자형
// intent.getExtras().getStringArray("EXTRA_MESSAGE"); // 배열형
// intent.getSerializableExtra("EXTRA_MESSAGE"); // 클래스형
});

버튼을 클릭하면 다른 화면이 표시되게 하고 싶을 때는 인텐트(Intent)객체를 사용해야 한다. 안드로이드를 구성하는 4대컴포넌트간(액티비티, 리시버, 프로바이더, 서비스)에 각종 의사전달에 사용되는 객체가 인텐트이다.

이번에는 액티비티간의 자료를 전달하는 것을 설명하고, 바로 ABA 이렇게 액티비티의 결과를 받은 경우에 사용되는 메소드에 대해서 알아보자.

우선 간단한 액티비티 전환(화면 변경)의 예제 소스이다. 전달한 값을 intent에 putExtra() 함수로 저장한 후, startActivity(intent) 호출하고, 호출되는 액티비티에서는 getIntent()로 intent를 받아 getExtras()로 자료를 추출한다.

 

- 화면을 구성하다보면, 액티비티간 이동을 ABA 이렇게 할 때가 있다. 위의 startActivity()을 할 경우, 사용자가 '뒤로가기' 버튼을 누르는 거나, 앱을 내렸다가 다시 화면을 띄우는 과정에서 예상치 못한 상황으로 결과를 잘못 받을 경우가 있어, startActivity() 대신 startActivityForResult()메소드 이용하고, BsetResult()로 결과 전송하고, AonActivityResult() 콜백 메소드가 호출되어, 전달받은 데이터를 받도록 처리해야 한다.

[Activity A]
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

public static final int REQUEST_CODE = 1000;
private EditText mNameEditText;
private EditText mAgeEditText;
private EditText mPhoneEditText;

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

mNameEditText = (EditText) findViewById(R.id.edit_name);
mAgeEditText = (EditText) findViewById(R.id.edit_age);
mPhoneEditText =(EditText) findViewById(R.id.edit_phoneNum);
findViewById(R.id.btn_call).setOnClickListener(this);
}

@Override
public void onClick(View v) {
Intent intent = new Intent(this, ActivityB.class);
intent.putExtra("name", mNameEditText.getText().toString());
intent.putExtra("age", mAgeEditText.getText().toString());
startActivityForResult(intent, REQUEST_CODE);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == REQUEST_CODE
&& resultCode == RESULT_OK
&& data != null) {
String result = data.getStringExtra("result");
Toast.makeText(ActivityB.this, result, Toast.LENGTH_SHORT).show();
}
}
}
[Activity B]
public class SecondActivity extends AppCompatActivity implements View.OnClickListener {

private TextView mMessageTextView;

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

Intent intent = getIntent(); // Activity A의 전달값 수신
String name = intent.getStringExtra("name");
String age = intent.getStringExtra("age");

mMessageTextView= findViewById(R.id.text_message);
mMessageTextView.setText(age + "살" + name);

findViewById(R.id.btn_result).setOnClickListener(this);
}

public void onClick(View v) {
Intent intent = new Intent(); // 결과를 전달할 준비
intent.putExtra("result", mMessageTextView.getText().toString()); // 결과값 저장
setResult(RESULT_OK, intent); // 결과값을 전달(Activity A)
finish();
}

}

다음에는 액티비티를 지정하지 않고, 암시적으로 Action 기반의 인텐트 이용방법에 대해 알아보고자 한다. 해당하는 Action 방식은 모바일의 연락처 이용, 전화걸기, 공유(카카오톡, 파일 이용) 등 다양하게 사용된다.

Posted by 목표를 가지고 달린다
,

View 정렬 방법(Vertical, Horizontal, Bottom, Top 등)

6. gravity : 자식뷰의 중력을 결정(Layout 에서 설정).. 중력이란 화면의 어느쪽에 정렬할 것인가? start, end, top, bottom, center, centerHorizontal, CenterVertical , |(파이프란인) 으로 여러 속성을 동시 설정가능

layout_gravity : 자식 뷰 각각의 중력을 결정... 자식 뷰(View에서 설정)에서 정의한다.

7. VIEW

View 객체들 배치 방법

8. 특정 View 간의 위치 배치
- 특정 뷰를 같이 배치하고자 할때, res/layout/activity_main.xml(해당 레이아웃 XML파일)의 뷰(EditView, Button, ImageView 등)에 아래와 같이 속성을 정의 한다.

layout_above="@id/[아이디]"
layout_toRightOf="@id/[아이디]"
layout_toEndOf="@id/[아이디]"
layout_toLeftOf="@id/[아이디]"
layout_toStartOf="@id/[아이디]"
layout_below="@id/[아이디]"

9. ConstraintLayout : 마지막에 나온 Layout으로, 제한(규칙)을 붙일 수 있는 레이아웃이다. 아래에 보면, 뷰들간에 속성을 정의할 수 있도록 되어 있다. 또한 이미지뷰를 상단에 꽉 채우려면, 여백을 0으로 설정하고, layout_widthmatch_constraints 속성을 준다. match_constraints 속성은 LinearLayout의 가중치(weight) 속성과 비슷. layout_width0dp로 주고, 좌우를 꽉 채울 때 사용.

--app:layout_constraintStart_toStartOf="[parent|다른뷰의 id]" : 현재 뷰의 왼쪽과 부모나 다른뷰의 왼쪽을 붙임
--app:layout_constraintEnd_toEndOf="[parent|다른뷰의 id]" : 현재 뷰의 오른쪽과 부모나 다른뷰의 오른쪽을 붙임
--app:layout_constraintTop_toTopOf="[parent|다른뷰의 id]" : 현재 뷰의 위쪽과 부모나 다른뷰의 위쪽을 붙임


...................

 

 

Posted by 목표를 가지고 달린다
,

기본 VIew 객체의 주요 속성(TextView, layout_weight 등)

1. TextView 속성

android:lines="1" -- 줄 수 지정
android:ellipsize="end" -- 줄수 지정에 따라, 글을 다 표현하지 못할 때, "아름다운 강산에 ..." 처럼 "..."로 표현함.
android:maxLines : 최대 표시줄 수 지정
android:minLines : 최소 표시줄 수 지정
android:textColor="#FF0000"
android:textStyle="bold|italic"

2. EditView 속성

android:hint="빈칸일 경우 표시할 문구"
android:inputType="textPassword" -- 입력 속성(textPassword, phone, textWebEmailAddress, number, numberPassword, time, date, datetime, numberDecimal, numberSigned
android:textAllCaps="true" -- 대문자 활성화

3. ImageView 속성

android:scaleType="fitXY"
-- 여백에 대해 이미지처리 방식으로, matrix(자바코드로 setMatrix()메소드에서 객체를 지정하여 회전, 확대/축소를 런타임에 할 수있음
-- fitXY : 가로세로에 이미지를 꽉 채움
-- fitStart : 비율을 유지하며 꽉채우는데, 여백이 있으면 시작 지점으로 정렬한다.
--fitCenter : (기본값) 비유을 유지하고 가운데 정렬
--fitEnd : 비율을 유지하고 여백이 있으면 끝에 정렬
--Center : 뷰보다 이미지가 클 때, 원본 크기를 유지하고 중앙을 위주로 표시한다.
--centerCrop : 뷰에 여백이 생기지 않도록 이미지가 확대/축소되며, 중앙 위주로 표시하고 남은 부분은 잘라낸다.(유용)
--centerInside

4. 기타 View
ProgressBar, SearchView, Spinner, CheckBox, RadioButton, RatingBar(별점 표시),

Switch(좌/우로 드래그하는 On/Off), SeekBar(핸들을 드래그해서 상태를 표시할 수있는 뷰)
<RadioGroup>
<RadioButton />
</RadioGroup>

<RatingBar
android:style="android:attr/ratingBarStyleSmall"
android:numStars="5"
android:rating="2.5"
android:stepSize="0.5" />

<SeekBar
android:max="100"
android:progress="20" />

<SearchView
android:iconifiedByDefault="true" -- "false"
/>

<ProgressBar
android:style="@style/Widget.AppCompat.ProgressBar" />

<ProgressBar
android:style="@style/Widget.AppCompat.ProgressBar.Horizontal" />

5. LinearLayout

--android:layout_height="0dp"
--android:layout_weight="1" -- height를 반드시 0으로 설정하고, 가중치를 이용하여 View간에 비율로 크기 설정 가능

6. gravity : 자식뷰의 중력을 결정(Layout 에서 설정).. 중력이란 화면의 어느쪽에 정렬할 것인가? start, end, top, bottom, center, centerHorizontal, CenterVertical , |(파이프란인) 으로 여러 속성을 동시 설정가능

layout_gravity : 자식 뷰 각각의 중력을 결정... 자식 뷰(View에서 설정)에서 정의한다.

 

 

 

Posted by 목표를 가지고 달린다
,

//이미지 뷰를 보여줌

ImageView.setVisibility(View.VISIBLE);

//이미지뷰 안보이게(공간은 남음)

ImageView.setVisibility(View.INVISIBLE);

//이미지뷰 아예 숨기기 공간조차 없어짐

ImageView.setVisibility(View.GONE);

2. ViewPage를 이용한 페이지 만들기 : https://yoo-hyeok.tistory.com/58?category=708422

2. Customized RadioButton : https://yoo-hyeok.tistory.com/57?category=708422

2. RadioButton : https://yoo-hyeok.tistory.com/55?category=708422

2. ListView 하기..리스트를 커스컴마이즈.. : https://yoo-hyeok.tistory.com/53?category=708422

2. Customized Dialog 하기 : https://yoo-hyeok.tistory.com/51?category=708422

2. 문자만 표시하는 Dialog 하기 : https://yoo-hyeok.tistory.com/50?category=708422

2. gif 이미지 넣기(동영상보다는 gif가 좋을 듯) : https://yoo-hyeok.tistory.com/48?category=708422

2. 최근 splash 방식 : velog.io/@pish11010/Android-Splash-Screen-%EA%B5%AC%ED%98%84

[Android] Splash Screen 구현

Splash Screen 은 일반적으로 앱이 실행될 때 나타나는 화면입니다.YouTube 앱 실행 시 나오는 잠깐 로고화면이 나오고 앱 메인화면으로 진입되는데, 여기서 로고가 나온 화면이 Splash Screen 입니다.이

velog.io

2. 어플 대표 화면 넣기 : https://yoo-hyeok.tistory.com/31?category=708422

[Android] 안드로이드 Splash Activity (어플 설명 액티비티, 어플 대표 화면) 만들기

카카오톡 실행시켜보면 처음에 카카오톡 이미지가 나오고 1초뒤에 카톡이 실행됩니다. 어플리케이션의 대표 레이아웃을 넣어 어플리케이션의 이미지를 담당하는 액티비티입니다. 만드는 방법은 간단합니다. 프로젝..

yoo-hyeok.tistory.com

3. 백버튼 눌렀을 때 알림창. https://yoo-hyeok.tistory.com/32?category=708422

유혁의 엉터리 개발

소프트웨어 개발자

yoo-hyeok.tistory.com

4. Json 사용 법 : https://yoo-hyeok.tistory.com/37?category=708422

[Android] 안드로이드 JSON 문자열 파싱(parsing)

String JSONData = "{"school":[{"subject1":"math"},{"subject2":"korean"}],"name":"유혁"}" (문법 생략) 안드로이드 스튜디오에서 파싱하기 ArrayList ArrList = new ArrayList(); //어레이 리..

yoo-hyeok.tistory.com

5. firebase push 이용법 : https://yoo-hyeok.tistory.com/43?category=708422

[Android] Firebase(Google Cloud Message) 를 이용한 푸시알림 구현 - (1) 환경설정

휴대폰 게임을 하다보면 중간중간에 아이템이 왔다며 푸시알림을 많이 받아보셨을 겁니다. 안드로이드 개발중에 이런 푸시알림을 주고싶을 때 GCM을 사용합니다. Firebase가 최근에 나온 버전이고 Firebase 만으로..

yoo-hyeok.tistory.com

Posted by 목표를 가지고 달린다
,

1. 스마트폰은 기본적으로 일정 시간동안 아무런 반응이 없으면 자동으로 화면이 꺼지게 됩니다.

원할 경우 실행되는 동안 화면을 안꺼지 게 할수 있습니다.
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
을 추가하게 되면 실행되는 동안 화면이 꺼지지 않습니다.

2. Dialog 타이틀바 없애기.

3. EditText에 이벤트 주기

EditText 이벤트는 addTextChangedListener() 를 사용하면 보다 쉽게 다룰수가 있었다.( setOnClickListener() 보다 좋음.)

et.addTextChangedListener(new TextWatcher(){   

   public void afterTextChanged(Editable arg0) {
    // TODO Auto-generated method stub    
   }   

   public void beforeTextChanged(CharSequence s, int start, int count,
     int after) {
    // TODO Auto-generated method stub    
   }

   public void onTextChanged(CharSequence s, int start, int before,
     int count) {
    // TODO Auto-generated method stub
    
   }
         
});

4. intent : https://yoo-hyeok.tistory.com/15?category=708422 putExtra를 단일 String, ArrayList 모두 가능.

5. 서비스 등록하기

Service는 background에서 처리를 계속할 수 있는 클래스이다.
Service는 기본적으로 activity를 가지지 않는다.

서비스를 구현하기 위한 3가지 절차
-- Service 클래스를 확장한 새로운 클래스 정의
-- Manifest file에 Service 선언 추가
-- App에서 Service 실행



1. 서비스를 실행하는 클래스 - 타이머를 이용한 반복 처리.

public class MyService extends Service implements Runnable {

    // 시작 ID
    private int mStartId;
    // 서비스에 대한 스레드에 연결된 Handler. 타이머 이용한 반복 처리시 사용.
    private Handler mHandler;
    // 서비스 동작여부 flag
    private boolean mRunning;
    // 타이머 설정 (2초)
    private static final int TIMER_PERIOD = 2 * 1000; 
    private static final int COUNT = 10;
    private int mCounter;


    // 서비스를 생성할 때 호출
    public void onCreate() {
        Log.e("MyService", "Service Created.");
        super.onCreate();
        mHandler = new Handler();
        mRunning = false;
    }


    // 서비스 시작할 때 호출. background에서의 처리가 시작됨.
    // startId : 서비스 시작요구 id. stopSelf에서 종료할 때 사용. 

     //onStart는 여러번 호출될 수 있기 때문에 식별자로 사용.

    public void onStart(Intent intent, int startId) {
        Log.e("MyService", "Service startId = " + startId);
        super.onStart(intent, startId);
        mStartId = startId;
        mCounter = COUNT;

        // 동작중이 아니면 run 메소드를 일정 시간 후에 시작
        if (!mRunning) {
              // this : 서비스 처리의 본체인 run 메소드. Runnable 인터페이스를 구현 필요.
              // postDelayed : 일정시간마다 메소드 호출
              mHandler.postDelayed(this, TIMER_PERIOD);
              mRunning = true;
        }
    }

 

    // 서비스의 종료시 호출
    public void onDestroy() {
        // onDestroy가 호출되어 서비스가 종료되어도 
        // postDelayed는 바로 정지되지 않고 다음 번 run 메소드를 호출.
        mRunning = false;
        super.onDestroy();
    }



    // 서비스 처리
    public void run() {
        if (!mRunning) {
            // 서비스 종료 요청이 들어온 경우 그냥 종료
            Log.e("MyService", "run after destory");
            return;
        } else if (--mCounter <= 0) {
            // 지정한 횟수 실행하면 스스로 종료
            Log.e("MyService", "stop Service id = "+mStartId);
            stopSelf(mStartId);
        } else {
            // 다음 작업을 다시 요구
            Log.e("MyService", "mCounter : " + mCounter);
            mHandler.postDelayed(this, TIMER_PERIOD);
        }
    }

    // 원격 메소드 호출을 위해 사용
    // 메서드 호출을 제공하지 않으면 null을 반환
    public IBinder onBind(Intent intent) {
        return null;
    }
}




2. 서비스 실행, 종료를 사용자가 요청하는 클래스

// 서비스 시작과 종료를 요구하는 Activity
public class MyServiceActivity extends Activity {

    ComponentName mService;    // 시작 서비스의 이름
    TextView mTextView;              // 서비스 상태 표시



    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mTextView = (TextView)findViewById(R.id.text_view);
        
        Button start = (Button)findViewById(R.id.start_button);
        start.setOnClickListener(new View.OnClickListener(){
            public void onClick(View v) {
                startHelloService();
            }});
        
        Button stop = (Button)findViewById(R.id.stop_button);
        stop.setOnClickListener(new View.OnClickListener(){
            public void onClick(View v) {
                stopHelloService();
            }});
    }



    // 서비스 시작 요청
    private void startHelloService() {
        mService = startService(new Intent(this, MyService.class));
        mTextView.append(mService.toShortString()+" started.\n");
    }

 

    // 실행한 서비스 중지 요청

    private void stopHelloService() {
        if (mService == null) {
            mTextView.append("No requested service.\n");
            return;
        }
        
        Intent i = new Intent();
        i.setComponent(mService);
        if (stopService(i))
            mTextView.append(mService.toShortString()+" is stopped.\n");
        else
            mTextView.append(mService.toShortString()+" is alrady stopped.\n");
    }
}


3. 사용자가 서비스 실행, 종료하는 화면 구성

<!-- 시작 -->
<Button android:id="@+id/start_button" android:text="Start"
android:layout_width="fill_parent" android:layout_height="wrap_content" />

<!-- 종료 -->
<Button android:id="@+id/stop_button" android:text="Stop"
android:layout_width="fill_parent" android:layout_height="wrap_content" />

<!-- 상태표시 -->
<TextView android:id="@+id/text_view_id"

android:editable="true"
android:layout_width="fill_parent" android:layout_height="fill_parent" />

6. 컴포넌트의 생명주기
컴포넌트의 생명주기는 컴포넌트를 인스턴스화 할 때 시작해서, 인스턴스가 사라질 때 종료됩니다.
액티비티의 경우 그 사이에 활성화, 비활성화가 될 수 있기 때문에 사용자에게 보이거나 , 또는 보이지 않을 수도 있습니다.

1. 액티비티 생명주기


액티비티는 필수적으로 세 가지의 상태를 가지고 있습니다.

▣ 활성화(activity) 또는 실행 (running) 상태

액티비티가 포그라운드 화면으로 사용자에게 보이는 상태입니다 ( 즉, 현재 태스크에서 스택의 최상위에 위치하는 것).
이 상태는 사용자 액션을 받을 수 있게 됩니다.


▣ 멈춤(paused) 상태

사용자 액션을 받진 못하지만 여전히 보여지고 있는 상태입니다. 즉 다른 액티비티가 그 위에 위치하지만 해당 액티비티가 화면을 전부 채우지 않거나 투명해서 멈춤 상태의 액티비티를 볼 수 있는 상태입니다.
이 상태의 액티비티는 살아있습니다 ( 모든 상태정보와 멤버를 유지 중 )
하지만 , 메모리 부족시엔 시스템에 의해 강제종료 될 수 있습니다.


▣ 정지 (stopped) 상태

완전히 다른 액티비티에 의해 가려진 상태입니다.더 이상 사용자에게 보이진 않지만 여전히 살아서(정보와 멤버유지) 있는 상태이죠.
여전히 보여지진 않기 때문에 메모리 부족시엔 강제종료 될 수 있습니다.



액티비티가 멈춤 또는 정지 상태라면, 시스템은 finish() 메소드를 호출하거나 프로세스를 강제종료 시킴으로서 메모리에서 제거할 수 있습니다.
종료된 액티비티가 다시 실행된다면, 다시 시작되어야 하고 이전 상태로 복구되어야 할 것입니다.



액티비티 상태변화


액티비티의 상태가 변하면 아래의 메소드가 호출됨으로써 변화가 통보되는데요.
이 메소들은 모두 프로텍티드(protected) 메소드 입니다.


여기의 7가지 메소드들은 오버라이드 할 수 있습니다.
단, 모든 액티비티는 최초 인스턴스 초기화를 위해 onCreate() 메소드는 무조건 구현해야 합니다.

또한, 액티비티 종료직전.... 마지막 기회가 될 수도 있는 시점에선 적절한 데이터 저장을 위해 onPause() 메소드도 구현해주면 좋겠네요.

액티비티 생명주기 메소드를 구현할 땐 항상 슈퍼클래스 버전을 호출하여야 합니다.
protected void onPause() {

super.onPause() ;

}


네스티드 루프(nested loop)


액티비티 생명주기 메소드를 구현하여 볼 수 있는 것은 아래와 같습니다.

▣ 액티비티 인타이어 라이프타임 ( entire lifetime )

onCreate() 와 onDestroy() 메소드 사이에서 발생합니다.
액티비티는 onCreate() 메소드에서 모든 초기 설정을 하고 onDestroy()에서 모든 리소스를 해제하죠.


▣ 액티비티 비지블 라이프타임 ( visible lifetime )

onStart() 메소드에서 onStop() 메소드 사이에서 발생합니다.
onStart() 메소드에서는 사용자 인터페이스의 변화 모니터를 위해 브로드캐스트 리시버를 등록할 수 있고 사용자가 보고있는 화면이 없을때엔 onStop() 메소드에서 제거할 수 있습니다. onStart() 와 onStop()은 액티비티가 사용자에게 보여지고 숨겨지는 상태이므로 여러번 호출 될 수 있습니다.


▣ 액티비티 포그라운드 라이프타임 ( foreground lifetime )

onResume() 메소드와 onPause() 메소드 사이에서 발생합니다.
이 기간동안 액티비티는 화면에서 다른 모든 액티비티보다 앞에 놓이며 사용자에게 보여집니다. onPause()는 기계가 꺼지거나 새로운 액티비티가 시작될 때 호출되고, onResume() 은 액티비티가 다시 복귀되거나 새로운 인텐트가 도착했을때 호출됩니다.
따라서 이 두개의 메소드 내용은 빠르고 가벼울 수록 좋겠네요.



생명주기 메소드가 하는 일

▣ onCreate()

액티비티가 최초 생성시에 호출됩니다. 초기화 설정을 하는 곳이지요. 보관된 상태의 액티비티가 있다면, 그 상태를 저장중인 Bundle 객체를 받습니다.
onStart() 메소드가 이어집니다. 강제종료가 불가능 합니다.


▣ onRestart()

액티비티가 정지 후 다시 시작되기 바로 직전에 호출됩니다.
onStart() 메소드가 이어집니다. 강제종료가 불가능 합니다.


▣ onStart()

액티비티가 사용자에게 보여지기 직전에 호출됩니다.
액티비티가 보여지게되면 onResume() 메소드가, 안보이게 되면 onStop() 메소드가 이어집니다.
강제종료가 불가능 합니다.


▣ onResume()

액티비티가 사용자와 상호작용하기 직전에 호출됩니다 (스택의 최상위에 위치)
onPause() 메소드가 이어집니다. 강제종료가 불가능 합니다.


▣ onPause()

시스템이 다른 액티비티를 시작하려 할 때 호출됩니다.
일반적으로 데이터 저장을 하기에 좋은 곳입니다.
하지만 소스코드의 속도가 빨라야합니다.
왜냐하면 이 메소드가 끝나기 전까진 다음 액티비티가 실행되지 않기 때문인데요,
액티비티가 되돌아오면 onResume(), 보이지않게되면 onStop() 이 이어집니다.
강제종료가 가능 합니다.


▣ onStop()

액티비티가 사용자에게 보이지 않을때 호출 됩니다.
액티비티가 제거되거나 다른 액티비티가 실행되어 해당 액티비티를 덮어버렸을 때, 호출되죠. 액티비티가 되돌아오면 onRestart(), 액티비티가 사라지면 onDestroy() 가 이어집니다.
강제종료가 가능 합니다.


▣ onDestroy()

액티비티 삭제 직전에 호출됩니다. 액티비티가 받는 마지막 호출 메소드가 되죠. 시스템이 메모리 확보를 위해 액티비티 인스턴스를 없애버려고 하거나 , finish() 메소드가 호출되면 호출되는 메소드입니다.

isFinishing() 메소드로 두 가지를 분기할 수 있습니다.



onStart() 메소드가 이어집니다. 강제종료가 불가능 합니다.



☞ 여기에서 onPause() 는 프로세스가 강제종료 되기 전에 호출되는 것입니다. 즉, 프로세스가 강제종료 될 때 onPause() 는 무조건 호출되는 유일한 곳이 됩니다. ( onStop(), onDestroy() 는 호출되지 않을 수 있어요 ), 따라서 이터 저장 등의 작업은 종료되기 직전에 호출되는 onPause() 에 구현해야 되겠네요.


액티비티 상태 저장하기


시스템이 액티비티를 강제종료 했을때, 사용자는 이전의 액티비티로 돌아가고 싶을 수 있습니다. 이럴 경우 액티비티가 강제종료 되기 전에 상태를 저장할 수 있는 onSaveInstanceState() 메소드를 구현하면 저장이 가능해 집니다.



즉, 액티비티가 파괴되기전에 호출되는 메소드 인데요. ( onPause() 호출 이전에 호출됩니다. )
이 메소드는 이름/값 쌍으로 이루어진 번들 객체(Bundle) 를 인수로 가집니다. 액티비티가 다시 시작되면 번들은 onSaveInstanceState() 와 onStart() 이후에 호출되는 onRestoreInstanceState() 에게 전달됩니다.



☞ onSaveInstanceState() , onRestoreInstanceState() 메소드는 생명주기 메소드는 아닙니다.
따라서 항상 호출되지는 않으며 특정 상황 ( 액티비티 강제종료전에 onSaveInstance() 호출처럼 ) 에서만 호출됩니다. 단, 사용자 액션에 의해 종료될 때는 ( 사용자가 직접종료 ) 호출되지 않습니다.
- 사용자가 되돌아가지 않을 생각으로 종료한 것으로 판단한 것이겠죠...

onSaveInstanceState() 는 액티비티의 일시적인 상태 저장을 위한 것이므로 , 데이터 등을 안전하게 저장하려면 onPause() 메소드에서 처리해야 합니다.


액티비티 생명주기 메소드의 순서


하나의 액티비티가 다른 액티비티를 시작할 때 하나는 멈추고 정지되며, 다른 하나는 시작되는 구조를 가집니다. 생명주기 메소드의 순서는 두 개의 액티비티가 동일 프로세스 안에 있을 때에 정의됩니다.

1. 현재 액티비티("A") 의 onPause() 가 호출됩니다.
2. 다음 시작되는 액티비티("B") 의 onCreate() -> onStart() -> onResume() 이 차례대로 호출됩니다
3. "B" 액티비티가 더 이상 사용되지 않으면 그것의 onStop() 이 호출됩니다.

7. PHP MySql 설치 등.. https://yoo-hyeok.tistory.com/16?category=708422

Posted by 목표를 가지고 달린다
,