Search
Write a publication
Pull to refresh

onActivityResult() is deprecated

В этой статье я поделюсь своим опытом перехода от onActivityResult() к Contract.

Краткое резюме статьи на Хабре и личный опыт.

Рассматриваю пример когда существует активити которое задает вопрос хотите ли вы выйти из аккаунта? и все что оно делает для нас это отвечает на вопрос да или нет? Соответственно нам нужно получить одну булиеву переменную.

Как я делал это раньше?

 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        binding.exitButton.setOnClickListener {
            startActivityForResult(
                Intent(requireContext(), ExitActivity::class.java),0
            )
        }
 }

 override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
      super.onActivityResult(requestCode, resultCode, data)
      if (resultCode == AppCompatActivity.RESULT_OK) {
          if (data?.getBooleanExtra(App.IS_SIGN_OUT, false) == true) {
              // exit fun
          }
      }
  }

Время onActivityResult подходит к концу, сейчас этот метод помечен как deprecated и есть вероятность что в будущих версиях андроид перестанет поддерживаться вовсе.

К нам на помощь спешат так называемые "контракты"!

И так как быстро и безболезненно заменить onActivityResult на свежий и контракт? Все очень просто. Вместо onActivityResult реализуем вот такой функционал:

private val signOutLauncher =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
            if (result.resultCode == Activity.RESULT_OK) {
                val data = result.data
                if (data?.getBooleanExtra(App.IS_SIGN_OUT, false) == true) {
                    // exit fun
                }
            }
        }

чтобы запустить лаунчер нужно выполнить не хитрую функцию:

signOutLauncher.launch(Intent(requireContext(), ExitActivity::class.java))

Код стал более аккуратным и мы избавились от Deprecated, но это еще не все, есть еще один не плохой плюс в контрактах, мы можем упростить код и сделать его переиспользываемым.

Для этого нужно создать класс контракт.

class SignOutContract : ActivityResultContract<String, Boolean>() {

    override fun createIntent(context: Context, input: String): Intent {
        return Intent(context, PopupActivity::class.java)
            .putExtra("my_key", input)
    }

    override fun parseResult(resultCode: Int, intent: Intent?): Boolean = when {
        resultCode != Activity.RESULT_OK -> false
        else -> intent?.getBooleanExtra(App.IS_SIGN_OUT, false) ?: false
    }

    override fun getSynchronousResult(
        context: Context,
        input: String
    ): SynchronousResult<Boolean>? {
        return if (input.isEmpty()) SynchronousResult(false) else null
    }
}

И собственно инициализация слушателя и вызов этого контракта:

val activityLauncher = registerForActivityResult(SignOutContract()) { result ->
    // используем result (в нашем случаае это Boolean)
    if (result) {
        // exit fun
    }
}
activityLauncher.launch("In yor activity needs string")

Теперь наш код может быть переиспользован и вызов этой активности стал в разы короче!

Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.