액티비티 컴포넌트 정리

2022. 12. 3. 02:06_Study/AndroidStudio

728x90

액티비티 컴포넌트 정리   🐇¸.•*¨*•¸.•*¨*•¸.•*¨*•¸.•*¨*•

해당 자료는 강의 학습자료이며, Do it! 깡샘의 안드로이드 앱 프로그래밍 with 코틀린을 참고하였습니다.


13-1 인텐트 이해하기

 

인텐트: 컴포넌트를 실행하려고 시스템에 전달하는 메시지

안드로이드의 컴포넌트 클래스라면 코드에서 직접 생성해서 실행할 수 없으며 시스템에서 인텐트의 정보를 분석해서 그에 맞는 컴포넌트를 실행해준다.

 

인텐트를 사용하는 이유: 컴포넌트를 실행하려고

 

액티비티는 manifest 파일에 <activity> 태그로 등록해야 하며 클래스 이름을 지정하는 name 속성은 생략불가며

startActivity() 함수가 인텐트를 시스템에 전달, 실행하며 Intent 생성자의 매개변수는 클래스 타입 레퍼런스 정보이다.

 

 

- 인텐트 엑스트라 데이터

인텐트에 컴포넌트를 실행을 요청할 때 데이터를 함께 전달하려면 엑스트라 데이터를 이용해야하며 엑스트라 데이터는 인텐트에 담는 부가정보라고 할 수 있다.

-> putExtra : 인텐트에 엑스트라 데이터를 추가하는 함수

-> get*Extra : 타입별로 데이터를 가져오기

val intent: Intent = Intent(this, DetailActivity::class.java)
intent.putExtra("data1","hello")
intent.putExtra("data2",10)
startActvity(intent)

//detail activity
val data1 = intent.getStringExtra("data1")
val data2 = intent.getIntExtra("data2")

 

 

화면을 전환했다가 다시 돌아올 때 사후처리를 해야할때 인텐트로 액티비티를 시작하는 방법 3가지

- public void startActivity(intent intent) : 사후처리가 필요 없을 때

- public void startActivityForResult(intent intent, int requestCode) : 필요

- ActivityResultLauncher :필요

 

        val requestLauncher: ActivityResultLauncher<Intent> = registerForActivityResult(
            ActivityResultContracts.StartActivityForResult())
             {
                val resultData = it.data?.getStringExtra("result")
                binding.mainResultView.text = "result : $resultData"
            }
            
            //    lateinit var binding: ActivityMainBinding 추가 필요
            //        binding= ActivityMainBinding.inflate(layoutInflater)
        	//setContentView(binding.root)

 

        intent.putExtra("resultData","world")
        setResult(RESULT_OK,intent)
        finish()

 

화면을 되돌릴 대는 finish() 함수를 이용 : 현재 화면에 보이는 액티비티를 종료해 달라고 시스템에 요청

setResult() 함수로는 결과를 어떻게 되돌릴지 지정 : OK, CANCELED

intent.putExtra("resultData","world")
setResult(RESULT_OK,intent)
setResult(RESULT_CANCELED, intent)
finish()

결과가 되돌아와서 다시 자신이 화면에 출력되면 onActivityResult() 함수가 자동으로 호출

requestCode : 인텐트를 시작하는 곳에서 인텐트를 구분하려고 설정한 요청코드

resultCode : 인텐트로 실행된 곳에서 돌려받은 결과 코드

data : 인텐트 객체로 이 객체의 결과 데이터가 있음

 

 

그림1

 

 

액티비티 화면 되돌리기 

ActivityResultLauncher : 액티비티에서 다양한 결과에대항 사후 처리를 제공

registerForActivityResult() 함수로 만드는 객체이며 함수의 매개변수에 실제 작업자인 Contract 객체와 결과를 처리하는 Callback 객체를 등록 ({} 괄호 안)한다.

 

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if(requestCode == 10 && resultCode == Activity.RESULT_OK){
            val result = data?.getStringExtra("resultData")
        }

 

Contract : 런처로 실행될 요청을 처리하는 역할로 ActivityResultContract를 상속받은 서브 클래스다.

contract : 실행자라고 생각하면 될거같다.

 

PickContract : 선택한 연락처의 Uri 획득

RequestPermission : 권한 요청, 허락 여부 파악

RequestMultiplePermission : 여러 권한을 동시에 요청

StartActivityForResult : 인텐트 발생, 액티비티 실행 결과 획득

TakePicturePreview : 사진촬영 후 비트맵 획득

TakePicture : 사진 촬영, 저장 ,비트맵 획득

 

 

 

인텐트는 실행할 컴포넌트 정보를 어떻게 설정하는지 에 따라 2가지로 나뉜다.

- 명시적 인텐트 : 클래스 타입 레퍼런스 정보를 활용한 인텐트 : 이름만 적음

- 암시적 인텐트 : 인텐트 필터 정보를 활용한 인텐트

 

 

인텐트 필터

앱 외부에서 인텐트로 실행할 수 있는 컴포넌트이어야 한다면 <intent-filter> 설정을 해줘야한다.

 

하위필터에는 <action>, <category>, <data> 태그를 이용해 정보를 설정

- <action> : 컴포넌트의 기능을 나타내는 문자열

- <category> : 컴포넌트가 포함되는 범주를 나타내는 문자열

- <data> : 컴포넌트에 필요한 데이터 정보

        <activity
            android:name=".DetailActivity"
            android:exported="true">
            <meta-data
                android:name="android.app.lib_name"
                android:value="" />
        </activity>
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

외부 앱과 연동하는 인텐트 필터 설정

manifest

exported = "true"로 바꿈

 

 

액티비티 인텐트 동작 방식

 

실행할 액티비티가 없을때나 1개, 혹은 여러 개 일때 시스템이 어떻게 처리하는지?

- 없을 때 : 시작하는 곳에서 오류

- 1개 : 문제없이 실행

- n개 : 사용자 선택으로 하나만 실행 ex) 연결프로그램

 

 

 

패키지 공개 상태

안드로이드 11 (API 레빌 30) 버전부터는 앱의 패키지 공개상태를 지정하지 않으면 외부 앱의 패키지 정보에 접근할 수 가 없다.

외부 앱을 연동하더라도 패키지 정보를 활용하지 않는다면 아무런 문제가 없다.

문제를 받는 함수

- PackageManager.getPackageinfo()

- PackageManager.queryIntentActivites()

- Intent.resolveActivity()

- PackageManager.getInstalledPackage()

- PackageManger.getInstalledApplications()

- bindService()