startActivityForResult deprecated에 관하여

최희창·2022년 6월 6일

Activity

목록 보기
1/2

배경

  • Deprecated된 이유는 다음과 같다.
    -> 1. AndroidX Activity와 Fragment에 도입된 Activity Result API 사용을 적극 권장.
    -> 2. 결과를 얻는 Activity를 실행하는 로직을 사용할 때, 메모리 부족으로 인해 프로세스와 Activity가 사라질 수 있다.
  • Activity Result API는 다른 Activity를 실행하는 코드는 Result Callback 부분과 분리해서 만들어야 한다. Result Callback은 프로세스와 Activity가 다시 생성될 때 사용할 수 있어야 하므로 다른 Activity를 실행하는 로직은 Activity가 생성될 때마다 Callback을 무조건 등록해야 한다.

startActivityForResult() / onActivityResult() 사용했을 시

  • 액티비티A와 액티비티B가 존재
  • A -> B 실행, 메모리가 부족해서 A가 소멸됨.
  • B 액티비티 종료 후 setResult()메서드로 결과값 넘김
  • A가 소멸되었다가 다시 생성되서 B에게 결과값을 요청한 줄 모름.

ActivityResultLauncher 객체와 registerForActivityResult()를 사용했을 시

  • 액티비티 A,B 존재
  • A -> B 실행, 메모리가 부족해서 A가 소멸됨.
  • B 액티비티 종료 후 setResult()로 결과값 넘김
  • A가 다시 생성돼도 registerForActivityResult()메서드가 다시 콜백을 등록해줘서 결과값을 받아온다.

Activity Result API

  • Activity Result API는 다른 액티비티를 실행하는 코드 위치에서 결과 콜백을 분리한다.
  • 메서드 registerForActivityResult() : 결과 콜백을 등록한다. ActivityResultContract 및 ActivityResultCallback을 가져와서 다른 액티비티를 실행하는 데 사용할 ActivityResultLauncher를 반환한다.
  • 클래스 ActivityResultContract<I,O> : 결과를 생성하는 데 필요한 입력 타입과 결과의 출력 타입을 정의한다.
    I : 입력 타입 / O : 출력 타입
    createIntent(Context context, I Input): startActivityForResult()에 사용할 수 있는 인텐트를 생성한다.
  • 인터페이스 ActivityResultCallback<'O'> : ActivityResultContract에 정의된 출력 타입의 객체를 가져오는 onActivityResult(O result)메서드가 포함된 단일 메서드 인터페이스.
  • 추상 클래스 ActivityResultLauncher<'I'> : ActivityResultcontract 실행 프로세스를 시작하기 위한 실행기

예제

    lateinit var getResultText: ActivityResultLauncher<Intent>
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val button = findViewById<Button>(R.id.button)

//registerForActivityResult()함수의 매개변수로 ActivityResultcontract,
//ActivityResultCallback을 전달해서 함수 호출 결과로 ActivityLauncher 인스턴스를 얻어낸다.
//registerForActivityResult()는 콜백을 등록하는 함수일 뿐, 
//실제 액티비티 실행이나 결과 요청은 여기서 반환된 ActivityResultLauncher 인스턴스가 담당한다.
        getResultText =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
                if (result.resultCode == RESULT_OK) {
                    val data = result.data?.getStringExtra("result")
                    Log.d("heec.choi", "getData:$data")
                }
            }

        button.setOnClickListener {
            val intent = Intent(this, MainActivity2::class.java)
            intent.putExtra("data", "heec.choi")
            //ActivityLauncher<I>는 ActivityResultContract<I> 타입과 일치하는 입력을 가져온다.
            //launch()함수를 호출하면 결과를 생성하는 프로세스가 시작된다.
            //사용자가 후속 활동을 완료하고 반환하면 ActivityResultCallback의 onActivityResult()함수가 실행됩니다.
            getResultText.launch(intent)
        }    

(MainActivity)

class MainActivity2 : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main2)
        val textView2 = findViewById<TextView>(R.id.text2)
        val button2 = findViewById<Button>(R.id.button2)

        val intent = intent
        textView2.text = intent.getStringExtra("data")

        button2.setOnClickListener {
            intent.putExtra("result", "happy coding")
            setResult(RESULT_OK, intent)
            if (!isFinishing) finish()
        }
    }
}

(MainActivity2)

profile
heec.choi

0개의 댓글