Android(안드로이드) 4. 안드로이드 Component - Activity

차선호·2023년 5월 15일
0

Android

목록 보기
4/5
post-thumbnail

Activity


생성

  • 모든 액티비티는 Manifest 파일에 선언되어야 함

    • 시작 액티비티는 태그 안에

    • action은 android:name=”android.intent.action.MAIN”

    • category에는 android:name=”android.intent.category.LAUNCHER”를 추가해야 한다.

  • AppCompatActivity( ) 상속해서 클래스 생성 → onCreate( ) 메서드 오버라이딩


생명 주기

  • onCreate( )

    • 액티비티가 생성될 때 호출

    • UI 초기화에 사용 (주로 View를 만드는 작업을 수행)

  • onStart( )

    • 액티비티가 사용자에게 표시되기 직전에 호출

    • onStop( )과 짝

    • 액티비티가 실행되는 중에만 어떤 작업을 하고 싶으면 onStrart( )에서 실행되게 하고 onStop( )에서 중단되게 하면 된다.

    • onStart( )는 focus가 없는 상태

    • 최초에 만들어 졌을 때 불린건지, background에서 있다가 와서 불린건지 구분이 필요

      • 최초에 만들어지면 초기화 같은 과정이 필요하기 때문에
  • onResume( )

    • 액티비티가 사용자와 상호작용하기 바로 직전에 호출됨

    • onResume( )은 focus가 있는 상태

    • onResume( ) 안에 함수들이 다 호출되고 나면 어플리케이션이 Activity Running 상태가 됨

    • 이 시점에 현재 액티비티가 액티비티 스택의 최상위에 있다.

    • onPause( )와 짝

  • onPause( )

    • 액티비티가 비활성화 되었을 때 호출

    • onResume( )과 짝

    • onPause( ) 호출될 때 View나 데이터를 Shared Preference를 통해 저장하고 나중에 onResume( ) 호출될 때 불러올 수 있다.

  • onStop( )

    • 액티비티가 더 이상 사용자자에게 보여지지 않을 때 호출

    • 이후에 onRestart( )를 거쳐서 onStart( )가 호출되면서 어플리케이션을 다시 호출할 수 있다.

    • 액티비티가 완전히 소멸된 것은 아니다 화면에서 내려왔을 뿐

  • onRestart( )

    • onStop( )이 호출되었다가 액티비티가 화면에 다시 보여질 때 onRestart( )를 거쳐서 onStart( )가 호출된다.
  • onDestory( )

    • 액티비티가 완전히 종료, 즉 어플리케이션을 완전히 종료했을 때 호출

    • 어플리케이션을 다시 실행시키면 onCreate( ) 부터 다시 시작

    • finish( ) 메서드가 호출되거나 시스템 메모리 확보를 위해 액티비티 제거할 때 사용

    • 메인 액티비티는 뒤로가기 해서 홈 화면으로 가도 작업 관리자에서 지우지 않는 이상 onDestory( ) 호출 안됨

  • 액티비티 전환 시 lifeCycle

    1. 기존 액티비티의 onPause() 메서드가 호출됩니다. 이때, 액티비티는 더 이상 화면에 보이지 않고, 사용자와의 상호작용이 불가능해집니다.(focus 잃음)

    2. 바뀔 액티비티의 onCreate() 메서드가 호출됩니다. 이때, 액티비티가 생성되고 레이아웃을 구성하게 됩니다.

    3. 바뀔 액티비티의 onStart() 메서드가 호출됩니다. 이때, 액티비티가 화면에 보이기 시작합니다.

    4. 바뀔 액티비티의 onResume() 메서드가 호출됩니다. 이때, 액티비티가 사용자와 상호작용할 수 있는 상태가 되며, 애니메이션 등의 효과가 표시됩니다. (focus 획득)

    5. 만약 바뀐 액티비티가 이전에 생성된 액티비티와 서로 다른 태스크에 속하게 된다면, 이전 액티비티는 onStop() 메서드를 호출합니다. 이때, 액티비티는 더 이상 화면에 보이지 않게 됩니다.

  • 화면 회전 시 life Cycle

    • 화면 회전하면 기존 화면이 Destory 되었다가 rotation된 화면을 재생성한다.

    • 기존 화면 destory : onPause( ) → onSaveInstanceState( ) → onStop( ) → on Destory( )

    • 회전 화면 생성 : onCreate( ) → onStart( ) → onRestoreInstanceState( ) → onResume( )

    • finish( )나 뒤로가기로 종료하면 onSaveInstanceState( )는 호출되지 않음


Intent

  • 어플리케이션 구성요소 4가지 간에 작업 수행을 위한 정보를 전달


명시적 인텐트

  • 실행하고자 하는 컴포넌트 이름과 클래스 명이 명시적으로 작성되어 호출할 대상을 확실히 알 수 있는 경우 사용
    val Intent = Intent(this, NextActivity::class.java)
    startActivity(intent)

암시적 인텐트

  • 인텐트의 액션과 데이터를 저장하긴 했지만 호출할 대상이 달라질 수 있는 경우에 사용

  • 특정 컴포넌트를 지정하지 않고, 원하는 작업 의도만 담고 컴포넌트를 실행할 수 있음

    • 액션과 데이터만 주고 어떤 컴포넌트를 사용할 지는 명시하지 않음

    • 시스템이 해당 의도를 적절히 처리할 수 있는 컴포넌트를 찾아 해당 작업을 처리

      • action, data, category만 비교한다.

      • 나머지 putExtra로 넣어준 건 시스템이 알 수 없어서 비교하지 않음

    • 이때 처리할 수 있는 컴포넌트가 여러 개라면 chooser가 나옴


Intent 구성 요소

  • Action

    • 수행할 액션 이름 (ex - ACTION_DIAL)
  • Data

    • 수행할 데이터의 URI
  • Category

    • 수행할 액션에 대한 추가적인 정보
  • Type

    • 수행할 인텐트 데이터의 명시적인 타입(MIME 타입) - video/mpeg
  • Component name

    • 대상 컴포넌트의 완전한 클래스 이름
  • Extras

    • 인텐트를 다루는 컴포넌트에 추가적으로 전달할 한 쌍의 키와 값
  • Flag

    • 동작 방식 결정 → 뒤로가기 시에 어떻게 이동할 지(history에 남길지)


Intent의 브로드캐스트 액션

  • 브로드캐스트 리시버가 받을 수 있는 Action
  • registReceiver(BroadcastRecceiver, IntentFilter) 메소드의 IntentFilter에 정의하거나 Mainfest의 태그 안에 정의할 수 있음


Intent Filter

  • 특정 인텐트를 받을지 말지를 정의하는 역할을 수행 이를 통해 컴포넌트의 특징이 정해짐
  • Intent Filter를 구성하는 요소는 인텐트 구성 요소와 동일


startActivity / requestActivity.launch

  • startActivity
    • 단방향으로 실행 → 결과 돌려받지 못함
  • Launcher
    • 결과를 다시 돌려 받을 수 있음



Android Permission


권한 종류

  • Install time permissions

    • 앱에서 설치 권한을 선언하면 설치할 때 권한 부여

    • 플레이 스토어에 명시되어 있는 권한

  • Runtime Permissions

    • 실행시 획득해야 하는 권한

    • 나머지는 선언만 하면 되지만 얘는 코드상으로 구현해야 함

  • Special Permissions

    • 플랫폼과 OEM만이 정의할 수 있는 권한


순서

  • Manifest에 선언

  • 앱에 권한이 부여되어 있는지 확인

    • 사용하려는 권한을 이미 부여 받았다면 다시 요청하지 않음

    • checkSelfPermission( ) 메서드를 사용하여 이미 권한이 있는지 확인 가능

      • PERMISSION_GRANTED or PERMISSION_DENIED를 반환 받음
  • 권한 요청

    • requestPermissions 메소드를 호출하면서 필요한 권한을 명시

    • 요청하려는 권한이 한 개 이상이면 String 배열로 넘겨줄 수 있음

  • 응답 처리

    • 응답

      • 사용자가 권한 요청에 응답하면 콜백 메서드인 onRequestPermissionsResult( )가 호출되고 여기서 결과 작업 진행
    • 거부

      • 사용자가 권한 요청을 거부하면 앱이 비정상 종료될 수 있음

      • dialog 띄워서 설정 화면으로 안내하는 것이 적절




Activity Task



Task

  • 관련된 실행 액티비티들을 순서대로 묶어 관리하는 것

  • 서로 다른 패키지의 액티비티가 실행되더라도 하나의 실행 흐름(Task) 안에 있게 됨


구조

  • Task는 스택의 형태로 구성 → 실행되는 액티비티들이 쌓이는 구조

  • 뒤로가기 누르면 top 액티비티가 없어지고 다음 액티비티가 top이 됨

  • 맨 마지막 root 액티비티가 없어지면 Task 완전 종료


Task 전환

  • 홈 화면에서 새로운 앱을 실행시키면 새로운 Task 생성

  • 최근 실행 앱 목록(작업 관리자)이 Task의 목록으로 top 액티비티들이 표시됨

  • 앱 목록에서 원하는 Task 선택 시 해당 Task 동작


Task 제어의 필요성

  • 반복되는 액티비티 또는 중복 실행 방지

  • 액티비티 실행 모드와 Flag로 제어




Activity 실행 모드



Activity 실행 모드 종류

  • standard

    • 기본 값으로 task 내에 중복된 액티비티 허용
  • singleTop

    • task 내에 top 액티비티와 동일한 액티비티를 실행하면 쌓지 않고 기존 top 액티비티 재사용

    • intent flag로 설정 가능 → Intent.FLAG_ACTIVITY_SINGLE_TOP

    • 기존 lifeCycle로는 처음 호출된건지, 다시 호출된건지 확인할 방법이 없다.

      • onPause( )와 onResume( )이 반복되서 실행될 것이다.

      • onNewIntent 함수 필요(onPause → onNewIntent → onResume)

  • singleTask

    • 위치와 상관없이 중복된 액티비티를 쌓지 않는다.

    • 기존의 있는 액티비티까지 위에 있는 액티비티들 제거해서 이동

    • 다른 Task에서 호출해도 무조건 자신의 Task로 오게 만들 수 있음

      • 외부에서 호출하게 하려면 exported = true 설정 필요
  • singleInstance

    • 중복을 허용하지 않을 뿐 아니라 혼자서 별도의 task 구성

    • task 내에는 오직 singleInstance로 설정된 액티비티 하나만 존재

  • 설정 방법

    • Manifest에 등록 → 등록 시에 동장 방식 결정

    • intent의 Flag 이용 → 런타임 시에 동작 방식 결정



Task 내 Activity 정리 및 변경

  • 액티비티 속성과 intent의 flag를 이용해 task 내의 특정 액티비티 제거 및 변경

    • 액티비티 속성 → Manifest 파일에 설정

      • 액티비티가 실행될 때마다 기본적으로 적용
    • flag 속성 → Intent 생성 후 설정

      • Manifest 파일에 선언된 액티비티의 속성을 재정의



noHistory / FLAG_ACTIVITY_NO_HISTORY

  • 해당 액티비티는 Task 스택에 쌓이지 않는다.

    • 다음 액티비티에도 뒤로가기 해도 얘는 없다 그 전의 액티비티로 이동
  • Manifest 설정 → android:noHistory=”true”

  • flag 설정 → intent.flags = Intent.FLAG_ACTIVITY_NO_HISTORY


FLAG_ACTIVITY_CLEAR_TASK

  • FLAG_ACTIVITY_NEW_TASK와 같이 사용되며 Task 내에서 다른 액티비티를 모두 삭제

    • intent.flags = intent.FLAG_ACTIVITY_CLEAR_TASK or intent.FLAG_ACTIVITY_NEW_TASK
  • 예시

    예를 들어, Task A가 있다고 가정하겠습니다. Task A에는 액티비티 A, 액티비티 B, 액티비티 C가 있습니다. 이때, 액티비티 C에서 FLAG_ACTIVITY_CLEAR_TASK와 FLAG_ACTIVITY_NEW_TASK 플래그를 사용하여 액티비티 D를 시작하면, Task B가 새로 생성되고 액티비티 D가 Task B에 포함됩니다. 그리고 이전 Task A의 모든 액티비티(A, B, C)는 삭제됩니다.

    FLAG_ACTIVITY_CLEAR_TASK 플래그를 사용하는 경우는 대개 로그아웃 기능을 구현할 때 사용됩니다. 로그아웃 기능을 구현할 때, 앱에서 사용자의 인증 토큰 등을 삭제하고 로그인 화면으로 이동해야 합니다. 이때, FLAG_ACTIVITY_CLEAR_TASK와 FLAG_ACTIVITY_NEW_TASK 플래그를 사용하여, 이전의 액티비티 스택을 모두 삭제하고 로그인 화면부터 새로운 Task를 시작합니다.



FLAG_ACTIVITY_CLEAR_TOP

  • 기존에 있던 액티비티 제거(상위 포함)하고 새로운 액티비티 생성

  • flag 설정 → intent.flags = intent.FLAG_ACTIVITY_CLEAR_TOP

  • FLAG_ACTIVITY_SINGLE_TOP과 조합하여 기존 액티비티 재활용

    • 액티비티 실행모드 singleTask과 동일해짐

    • intent.flags = intent.FLAG_ACTIVITY_CLEAR_TOP or intent.FLAG_ACTIVITY_SINGLE_TOP

    • 해당 액티비티가 noHistory가 아닌지 확인해보고 실행

profile
dkssud!

0개의 댓글