'인스타그램 클론 프로젝트'를 진행하다가 startActivityForResult()를 더이상 지원하지 않는다는 이슈때문에 다른 함수를 사용했어야 했다.
따라서, startActivityForResult()를 대체할 registerForActivityResult()에 대해 분석해보고자 한다.
startActivityForResult()를 통해 콜백을 등록하고, onActivityResult()에서 콜백을 처리한다.
그러나 이런 방식을 사용했을 때 메모리 부족으로 작업이 소멸할 수 있다.
=> 따라서, 다른 activity를 실행하는 부분에서 콜백을 분리시켜야 한다.
Acitivity로부터 데이터를 전달받기 위해서는 startActivityForResult(Intent, Int) 함수를 이용해 새로운 화면을 호출한다. 그 후, onAcitivityResult(int, int, Intent) 함수로부터 넘어온 데이터를 처리한다.
class OldActivityResultSampleActivity : AppCompatActivity() {
private val request_second_code = 100
private fun startSecondView() {
val intent = Intent(/** context */, ResultSecondActivity::class.java)
startActivityForResult(intent, request_second_code) // ◀ Deprecated된 함수
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data) // ◀ Deprecated된 함수
if (requestCode == request_second_code) {
// action to do something
}
}
}
ActivityResultContract 및 ActivityResultCallback을 가져와 다른 activity를 실행하는 데 사용할 ActivityResultLauncher를 반환한다.
새로운 표기법에서는 Intent를 작성하는 방법은 동일하지만, 큰 차이점은 startActivityForResult(Intent, int) 함수를 호출하지 않는다는 것이다.
- A 액티비티에서 먼저 registerForActivityResult() API를 정의한다.
- ActivityResult를 받기 위해 파라미터로 전달하는
ActivityResultCallback의 StartActivityForResult 함수를 사용하여 기존onActivityResult(int, int, Intent)와 동일한 결과를 처리한다.
- result 객체를 인자로 받아와 'resultCode'와 'data'에 접근 가능
- resultCode를 이용해 'RESULT_OK' 인지 확인
- result.data를 이용해 다른 액티비티에서 보내온 Intent Data를 이용 가능
ActivityResultLauncher을 통해 시작시킨다. 즉, Intent 전달로 새로운 Activity를 호출한다.- B 액티비티에서 데이터를 실어 A 액티비티로 보내주기 위해,
setResult()함수에 resultCode와 Intent 데이터를 넣어준다.
import androidx.activity.result.contract.ActivityResultContracts.*
class ActivityResultSampleActivity : AppCompatActivity() {
val requestActivity: ActivityResultLauncher<Intent> = registerForActivityResult(
StartActivityForResult() // ◀ StartActivityForResult 처리를 담당
) { activityResult ->
// action to do something
}
private fun startSecondView() {
val intent = Intent(/** context */, ResultSecondActivity::class.java)
requestActivity.launch(intent)
}
}
setResult 함수 사용secondActivityBtn.setOnClickListener {
val intent = Intent(this, MainActivity::class.java).apply {
putExtra(MainActivity.STRING_INTENT_KEY, "Good")
}
setResult(RESULT_OK, intent)
if (!isFinishing) finish()
ActivityResult 타입 데이터를 리턴한다.@SuppressLint("BanParcelableUsage")
public final class ActivityResult implements Parcelable {
private final int mResultCode;
@Nullable
private final Intent mData;
/**
* Create a new instance
*
* @param resultCode status to indicate the success of the operation
* @param data an intent that carries the result data
*/
public ActivityResult(int resultCode, @Nullable Intent data) {
mResultCode = resultCode;
mData = data;
}
ActivityResult(Parcel in) {
mResultCode = in.readInt();
mData = in.readInt() == 0 ? null : Intent.CREATOR.createFromParcel(in);
}