사용자에게 UI 화면을 제공하는데 기본이 되는 앱 컴포넌트.
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 할 수 있다.
화면 회전과 같은 특정 경우에는 액티비티가 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") }
}
실행하고자 하는 컴포넌트 이름과 클래스명을 명시적으로 작성하여 호출할 대상을 확실히 알 수 있는 경우에 사용
값만 전달하는 경우
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를 받아 실행된다.
Action : 수행할 액션 이름
Data : 수행할 데이터 URI
Category : 수행할 액션에 대한 추가적인 정보
Type : 수행할 인텐트 데이터의 명시적인 타입(video, mpeg, ..)
Component name : 대상 컴포넌트 클래스 이름
Extras : 컴포넌트에 전달할 한 쌍의 키/값
어떠한 intent 액션이 발생했을 때 액티비티가 그 액션을 받아서 수행할지 안할지를 intent filter에 정의해서 처리한다.
예를 들어 MainActivity는 MAIN 이라는 action을 가지는 인텐트가 시작되는 경우 이를 받아서 실행한다.