안드로이드 Activity & Intent

이영준·2023년 4월 5일
0

📌 Activity

사용자에게 UI 화면을 제공하는데 기본이 되는 앱 컴포넌트.

  • 하나의 앱은 앱 최초 실행시 보여지는 하나의 메인 액티비티를 가짐.
  • 반드시 모든 액티비티는 Manifest에 선언되어야 함

🔑 액티비티 생명주기

https://developer.android.com/guide/components/activities/activity-lifecycle?hl=ko

onStart()는 포커스가 없는 상태, 즉 사용자와의 상호작용이 시작안된 상태로 액티비티가 사용자에게 표시되기 직전에 호출된다.
onStop()과 짝을 이뤄 사용된다

onResume() 부터 다시 상호작용이 시작된다. 즉, 사용자와 상호작용하기 바로 전에 호출된다. 액티비티가 비활성화 되었을 때 호출되는 onPause()와 짝을 이룬다.

onStop() 은 액티비티가 더 이상 사용자에게 보여지지 않을 때 호출된다. 하지만 아직 완전히 액티비티가 소멸된 것은 아니다. 이 경우에 onRestart() 를 거쳐 액티비티를 다시실행할 수도 있다.

예를 들어 액티비티에서 다른 액티비티를 호출했다가 다시 뒤로가기를 눌러 돌아오면

onCreate -> onStart -> onResume -> (액티비티 시작)
onPause -> onStop -> (다른 액티비티로 화면 이동)
참고로 onPause와 onStop 사이에 다른 액티비티의
(onCreate -> onStart -> onResume)과정이 일어난다.

onRestart -> onStart-> onResume (액티비티로 돌아옴)
순으로 실행된다.

onPause()onStop() 상태에서는 다른 우선순위가 높은 애플리케이션 실행에 필요한 메모리가 부족해지면 시스템이 알아서 앱을 kill 할 수 있다.

🔑 onDestroy에 대한 대응 (onSaveInstanceState)

화면 회전과 같은 특정 경우에는 액티비티가 destroy된 다음 새로 onCreate 하는 방식으로 화면이 재구성된다.


이 때는 onSaveInstanceState를 오버라이딩하여 기존 액티비티의 데이터를 백업해두는 등의 작업을 통해 처리할 수 있다.

onCreate함수를 보면
override fun onCreate(savedInstanceState: Bundle?)와 같이 되어있는데
이 때 이 인자로 들어가는 savedInstanceState 가 불러져 오며 내가 저장한 savedInstanceState가 있다면 그 안의 값이 가져온다.

override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putInt("value", value)
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityDetailBinding.inflate(layoutInflater)
        setContentView(binding.root)

        if (savedInstanceState != null) {
            value = savedInstanceState.run { savedInstanceState.getInt("value") }
        }

📌 Intent 구분

🔑 명시적 인텐트

실행하고자 하는 컴포넌트 이름과 클래스명을 명시적으로 작성하여 호출할 대상을 확실히 알 수 있는 경우에 사용

값만 전달하는 경우

val intent = Intent(this, NextActivity::class.java)
            intent.putExtra("Key", "MainActiviy에서 명시적 인텐트 전달")
            startActivity(intent)

값 전달 및 결과 값 받아올 경우에는
ActivityResultLauncher 객체를 만들어
.launch로 인텐트를 전달한다.

        val requestActivity = registerForActivityResult(
            ActivityResultContracts.StartActivityForResult()) {
            if(it.resultCode == RESULT_OK) {
                val intent = it.data
                val resurnValue = intent?.getStringExtra("to_main")
                Toast.makeText(this, resurnValue, Toast.LENGTH_SHORT).show();
            }
        }

        binding.explicit2Button.setOnClickListener{
            Toast.makeText(this,"명시적 인텐트-결과받기", Toast.LENGTH_SHORT).show()

            val intent = Intent(this, NextActivity::class.java)
            intent.putExtra("Key", "MainActiviy에서 명시적 인텐트 전달, 결과를 넘겨주세요.")
            //결과 돌려받기.
            requestActivity.launch(intent)
        }

다른 앱의 컴포넌트 열기

binding.btnOtherApp.setOnClickListener {
            val intent = Intent()
            val cname = ComponentName("com.example.component_1", "com.example.component_1.MainActivity")
            intent.component = cname
            startActivity(intent)
        }

위와 같이 패키지명을 명시해 다른 앱의 컴포넌트를 열 수도 있다.

🔑 암시적 인텐트

인텐트의 액션과 데이터를 지정하긴 했지만, 호출할 대상이 달라질 수 있는 경우에 사용.
반드시 특정 컴포넌트를 지정하지 않고, 원하는 작업 의도만 담고 컴포넌트 실행
따라서 시스템은 해당 인텐트를 적절히 처리할 수 있는 컴포넌트를 찾아 해당 작업을 처리한다.

다음은 암시적 인텐트로 ACTION_VIEW를 받을 수 있는 애플리케이션을 실행하는 예제이다.

        binding.implicitButton.setOnClickListener{
            Toast.makeText(this,"암시적 인텐트", Toast.LENGTH_SHORT).show()

            //암시적 인텐트 목적에 맞는 호출 : 지도보기, 연락처보기, 인터넷, SNS 공유 등등.
//            val intent = Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com/"))
            //지도
//            val intent = Intent(Intent.ACTION_VIEW, Uri.parse("geo:36.1048788, 128.4185357"))
            // 연락처
            val intent = Intent(Intent.ACTION_VIEW, Uri.parse("content://contacts/people/1"))
            startActivity(intent)
        }

위처럼 "geo:" uri를 담아 실행시키면 지도 앱이 intent를 받아 실행된다.

📌 Intent 구성요소

Action : 수행할 액션 이름
Data : 수행할 데이터 URI
Category : 수행할 액션에 대한 추가적인 정보
Type : 수행할 인텐트 데이터의 명시적인 타입(video, mpeg, ..)
Component name : 대상 컴포넌트 클래스 이름
Extras : 컴포넌트에 전달할 한 쌍의 키/값

🔑 Intent Filter

어떠한 intent 액션이 발생했을 때 액티비티가 그 액션을 받아서 수행할지 안할지를 intent filter에 정의해서 처리한다.


예를 들어 MainActivity는 MAIN 이라는 action을 가지는 인텐트가 시작되는 경우 이를 받아서 실행한다.

profile
컴퓨터와 교육 그사이 어딘가

0개의 댓글