안드로이드 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개의 댓글

관련 채용 정보