我最近发现onActivityResult已弃用。我们该怎么处理呢?

有什么替代方案吗?


当前回答

startActivityForResult和onActivityResult在android 10 API 30中已弃用,现在我们有了一种新的方法来使用registerForActivityResult来获得结果

resultContract =
    registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
        if (result.resultCode == Activity.RESULT_OK) {
            // There are no request codes
            val country = result.data?.getParcelableExtra<Country>("Country")
            showLiveDemoDialogue(country)
        }
    }

并启动活动

val intent = Intent(this, CountriesListActivity::class.java)
        resultContract.launch(intent)

但你应该在呼叫发射前注册然后发射到你想去的任何地方。 否则,您将得到这个异常

attempting to register while current state is RESUMED. LifecycleOwners must call register before they are STARTED.

其他回答

如果您正在使用SMS同意API,则使用以下代码(Kotlin):

resultLauncher.launch( consentIntent
                            )

    var resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    if (result.resultCode == Activity.RESULT_OK) {
        // There are no request codes
    //    val data: Intent? = result.data
        val message = result.data?.getStringExtra(SmsRetriever.EXTRA_SMS_MESSAGE)
        getOtpFromMessage(message)

    }
}

在替换已弃用的方法startActivityForResult(…)时,需要遵循4个简单的步骤。

In place of overridden method onActivityResult(..) - ActivityResultLauncher<Intent> activityResultLaunch = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() { @Override public void onActivityResult(ActivityResult result) { if (result.getResultCode() == 123) { // ToDo : Do your stuff... } else if(result.getResultCode() == 321) { // ToDo : Do your stuff... } } });

对于多个自定义请求,将条件附加为

if (result.getResultCode() == 123) {
..
} else if(result.getResultCode() == 131){
..
} // so on..

Imports : import androidx.activity.result.ActivityResult; import androidx.activity.result.ActivityResultCallback; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; In place of startActivityForResult(intent, 123), use Intent intent = new Intent(this, SampleActivity.class); activityResultLaunch.launch(intent); In SampleActivity.java class, while returning back to source activity, code will remain the same like - Intent intent = new Intent(); setResult(123, intent); finish();

编码快乐!:)

对于那些具有多个requestCode的片段,并且如果您不确定如何处理这些requestCode的多个结果,那么您需要了解requestCode在新方法中是无用的。

我想象你以前的编码方式是这样的:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (resultCode == Activity.RESULT_CODE) {
        when (requestCode) {
            REQUEST_TAKE_PHOTO -> {
                // handle photo from camera
            }
            REQUEST_PICK_IMAGE_FROM_GALLERY -> {
                // handle image from gallery
            }
        }
    }
}

在新的API中,你需要在一个单独的ActivityResultContract中实现每个请求的结果:

val takePhotoForResult = registerForActivityResult(StartActivityForResult()) { result: ActivityResult ->
    if (result.resultCode == Activity.RESULT_OK) {
        val intent = result.data
        // handle photo from camera
    }
}

val pickImageFromGalleryForResult = registerForActivityResult(StartActivityForResult()) { result: ActivityResult ->
    if (result.resultCode == Activity.RESULT_OK) {
        val intent = result.data
        // handle image from gallery
    }
}

然后你需要像这样开始这些活动/意图:

private fun startTakePhotoActivity() {
    takePhotoForResult.launch(Intent(requireActivity(), TakePhotoActivity::class.java))
}

private fun pickImageFromGallery() {
    val pickIntent = Intent(Intent.ACTION_PICK)
    pickIntent.setDataAndType(
        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
        "image/*"
    )
    pickImageFromGalleryForResult.launch(pickIntent)
}

通过这样做,你可以在你的项目中摆脱数百个const val REQUEST_值。

从现在开始,startActivityForResult()已经被弃用,所以使用new方法代替。

芬兰湾的科特林的例子

    fun openActivityForResult() {
        startForResult.launch(Intent(this, AnotherActivity::class.java))
    }


    val startForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { 
    result: ActivityResult ->
        if (result.resultCode == Activity.RESULT_OK) {
            val intent = result.data
            // Handle the Intent
            //do stuff here
        }
    }

在芬兰湾的科特林 我改变了我的代码

startActivityForResult(intent, Constants.MY_CODE_REQUEST)

and

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    super.onActivityResult(requestCode, resultCode, data)
    if (resultCode == Activity.RESULT_OK) {
        when (requestCode) {
            Constants.MY_CODE_REQUEST -> {
            ...
}

to

registerForActivityResult(StartActivityForResult()) { result ->
    onActivityResult(Constants.MY_CODE_REQUEST, result)
}.launch(intent)

and

private fun onActivityResult(requestCode: Int, result: ActivityResult) {
    if(result.resultCode == Activity.RESULT_OK) {
        val intent = result.data
        when (requestCode) {
            Constants.MY_CODE_REQUEST -> {
            ...

我希望这对你有用。: D