[Android Studio] registerForActivityResult

Minjun Kim·2023년 8월 5일
2

Android

목록 보기
3/47
post-thumbnail

액티비티 간에 데이터를 주고 받을 수 있다.

  • 공식문서와 포스팅된 글들을 통해 이해하려고 했지만, 현재의 지식으론 택도 없는 듯하다...

  • 따라서 키워드와 사용법 정도를 정리하려 한다.


📄 공식문서

  • Activity 또는 Fragment에 있을 때, Activity Result API에서 제공하는 registerForActivityResult() API를 통해서 결과 콜백을 등록할 수 있다.

  • 여기서 registerForActivityResult()는 ActivityResultContract와 ActivityResultCallback을 가져와서 다른 activity를 실행하는 데 사용할 ActivityResultLauncher를 반환한다.

  • ActivityResultContract는 우리가 결과를 생성하는 데 필요한 입력의 형태와 결과를 출력하는 형태를 정의하고 우리가 intent를 사용하는 작업의 기본적인 계약을 제공한다.

구글링 + 공식문서로 대략적이나마 이해한 내용이나 정리해보자.

1. registerForActivityResult 란?

  • Activity Result API 라는 API(?)에서 제공하는 기능이다.

  • 결과 콜백 을 통해서 액티비티 간 데이터 전달을 한다.

  • ActivityResultContractActivityResultCallback 을 인자로 가지고,
    이를 사용하여 다른 액티비티를 실행하는 ActivityResultLauncher 를 반환한다.

  • ActivityResultContract 는 받는 데이터 타입과 반환값 데이터 타입을 정의한다. (아님 말고)

  • 즉, ActivityResultLauncher 를 반환하여 데이터 전달을 한다. (아님 말고)

  • 추가로, 왜 결과 콜백을 사용하는가?

📄 공식문서에 따르면,

결과를 얻기 위해 Activity를 시작할 때, 메모리 부족으로 인해 프로세스와 Activity가 소멸될 수 있다. 따라서 Activity Result API는 다른 Activity를 실행하는 코드에서 결과 콜백을 분리한다. 프로세스 및 작업을 다시 생성할 때 결과 콜백을 사용할 수 있어야 하므로 다른 작업을 시작하는 로직이 사용자 입력 또는 다른 비즈니스 로직에 따라서만 발생하더라도 작업이 생성될 때마다 콜백을 무조건 등록해야 합니다.

... 라고 한다.


사용법이나 알아보도록 하자.

2. registerForActivityResult 사용법

  • 데이터를 전달하는 액티비티와 수신하는 액티비티, 2개의 .KT 파일에 코드 작성을 해야 한다.

  • 회원가입 액티비티에서 입력한 아이디와 비밀번호를 로그인 액티비티로 전달하는 상황이다.

  • ActivityResult : 전달하는 데이터

  • intent.putExtra("name", data) : 데이터 전달 메소드

  • resultLauncher.launch(intent) : startActivity와 동일한 기능

01. 데이터를 전달하는 액티비티에 작성하는 코드

  • ActivityResult를 전달하는 액티비티에 setResult 등록
  intent.putExtra("id", strId)					// 아이디 전달
  intent.putExtra("password", strPassword)		// 비밀번호 전달
  setResult(RESULT_OK, intent)					// RESULT_OK 전달하여 ActivityResult 수신 구문 실행
  finish()

02. 데이터를 수신하는 액티비티에서 작성하는 코드

  • ActivityResult를 받고자 하는 액티비티에 Callback 등록

1) ActivityResultLauncher 자료형의 변수를 선언한다.

  lateinit var resultLauncher: ActivityResultLauncher<Intent>

2) ActivityResult를 받는 구문을 작성한다.

resultLauncher =
	registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->		// it -> result
    	if (result.resultCode == RESULT_OK) {
        	val id = result.data?.getStringExtra("id") ?: ""				// 아이디 수신 혹은 ""
            val password = result.data?.getStringExtra("password") ?: ""	// 비밀번호 수신 혹은 ""

			edit_textId.setText(id)					// 아이디에 입력
            edit_textPassword.setText(password)     // 비밀번호에 입력
	}
}

3) ActivityResult를 받아올 액티비티를 실행한다.

  val btn_SignUp = findViewById<Button>(R.id.btn_SignUp)		// 회원가입 버튼

  // 회원가입 버튼 클릭
  btn_SignUp.setOnClickListener {
      val intent = Intent(this, SignUpActivity::class.java)		// SignUpActivity Intent
      resultLauncher.launch(intent)								// SignUpActivity 이동 및 ActivityResult 수신
  }

03. 전체 소스 코드

// SignUpActivity : ActivityResult를 넘겨주는 액티비티


class SignUpActivity : AppCompatActivity() {
	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		setContentView(R.layout.activity_sign_up)

		val btn_Single = findViewById<Button>(R.id.btn_Single)      // 회원가입 버튼
        
        // 회원가입 버튼 클릭
		btn_Single.setOnClickListener {     
			val editText_name = findViewById<EditText>(R.id.editText_name)
			val strName = editText_name.text.toString()

			val editText_id = findViewById<EditText>(R.id.editText_id)
			val strId = editText_id.text.toString()

			val editText_paasword = findViewById<EditText>(R.id.editText_password)
			val strPassword = editText_paasword.text.toString()

			val isName = strName.isEmpty()          // 이름 텍스트가 비어있는지 확인, 초기값 : true
			val isId = strId.isEmpty()              // 아이디 텍스트가 비어있는지 확인, 초기값 : true
			val isPassword = strPassword.isEmpty()  // 비밀번호 텍스트가 비어있는지 확인, 초기값 : true

			// 이름, 이아디, 비밀번호 모두 입력 시 finish() 호출
			if (isName || isId || isPassword) {
				Toast.makeText(this, "입력되지 않은 정보가 있습니다.", Toast.LENGTH_SHORT).show()
			} else {
				intent.putExtra("id", strId)        			// 아이디 전달
				intent.putExtra("password", strPassword)        // 비밀번호 전달
				setResult(RESULT_OK, intent)        			// RESULT_OK 전달하여 ActivityResult 수신 구문 실행
				finish()
			}
		}
	}
}

// SingleActivity : ActivityResult를 넘겨 받는 액티비티


class SingleActivity : AppCompatActivity() {
	private lateinit var resultLauncher: ActivityResultLauncher<Intent>

	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		setContentView(R.layout.activity_single)

		val edit_textId = findViewById<EditText>(R.id.editTextId)       // 아이디 입력 텍스트
		val strId = edit_textId.text.toString()							// 아이디

		val edit_textPassword =
			findViewById<EditText>(R.id.editTextPassword)       // 비밀번호 입력 텍스트
		val strPassword = edit_textPassword.text.toString()     // 비밀번호

		val btn_Home = findViewById<Button>(R.id.btn_Home)      // 로그인 버튼
		// 로그인 버튼 클릭
		btn_Home.setOnClickListener {
			val intent = Intent(this, HomeActivity::class.java)     // HomeActivity Intent
			intent.putExtra("ID", strId)        // ID-strId 전달

			val strId = edit_textId.text.toString()					// 아이디
			val strPassword = edit_textPassword.text.toString()		// 비밀번호

			// 아이디 & 비밀번호 입력 시 로그인 버튼 활성
			if (strId.isEmpty() || strPassword.isEmpty()) {
				Toast.makeText(
					this,
					"아이디/비밀번호를 확인해주세요",
					Toast.LENGTH_SHORT
				).show()
			} else {
				Toast.makeText(this, "로그인 성공", Toast.LENGTH_SHORT).show()
				startActivity(intent)       // HomeActivity 이동
			}
		}

		val btn_SignUp = findViewById<Button>(R.id.btn_SignUp)			// 회원가입 버튼
		// 회원가입 버튼 클릭
		btn_SignUp.setOnClickListener {
			val intent = Intent(this, SignUpActivity::class.java)		// SignUpActivity Intent
			resultLauncher.launch(intent)       // SignUpActivity 이동 및 ActivityResult 수신
		}

		resultLauncher =
			registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->     // it -> result
				if (result.resultCode == RESULT_OK) {
					val id = result.data?.getStringExtra("id") ?: ""				// 아이디 수신 혹은 ""
					val password = result.data?.getStringExtra("password") ?: ""	// 비밀번호 수신 혹은 ""

					edit_textId.setText(id)					// 아이디에 입력
					edit_textPassword.setText(password)		// 비밀번호에 입력
				}
			}

	}
}

🔎 [참고 사이트]

ho-taek.log
jige.tistory
minchanyoun.tistory

profile
응애 나 아기 뉴비

1개의 댓글

comment-user-thumbnail
2024년 3월 25일

감사합니다 ^^

답글 달기