Reputation: 9479
I am calling activity B from activity A using the ActivityResultLauncher
and setting the result from activity B when the task is done. This works perfectly if orientation is not changed. The problem is when I change orientation from activity B and then setting the result, then registerForActivityResult
of activity A is not called. Could someone let me know, what could be the issue?
Note: I do not face this issue if I am using startActivityForResult
and onActivityResult
. I changed this to ActivityResultLauncher
as startActivityForResult
became deprecated.
activity A sample code:
private lateinit var launcher: ActivityResultLauncher<Intent>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(layout)
setLauncherResult()
}
private fun setLauncherResult() {
launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
if (result.resultCode == Activity.RESULT_OK) {
//Do operations here
}
}
//On button click starting activity B using launcher
val intent = Intent(activityA, activityB)
launcher.launch(intent)
}
activity B sample code:
//setting result
val intent = Intent()
//set intent extras
setResult(Activity.RESULT_OK, intent)
finish()
Upvotes: 9
Views: 11518
Reputation: 8923
Try moving the registerForActivityResult
assignment of launcher
to onCreateView()
(override it if you haven't already). Putting it here, I'm not getting the "is attempting to register while current state is STARTED" RuntimeException
in OnCreateView()
as it would with onResume()
or later. The advantage of OnCreateView()
over OnCreate()
seems to be that the launcher
variable will get re-set on theme day/night changes as well as just orientation changes.
Also see the Configuration change & Process death section here for more discussion.
I know the official dox say it's safe to set it before anything else in the class, but theme changes broke .launch()
, and this location appears to work for me.
Upvotes: 0
Reputation: 9093
Everytime orientation changes it calls onCreate
and it resets your views & Other variables like launcher
are re-assigned. So you can follow the example shown in official document here: https://developer.android.com/training/basics/intents/result#launch
And pull your launcher
assignment out of onCreate
as following (This worked for me):
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private val startForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
if (result.resultCode == Activity.RESULT_OK) {
//do your stuff here
binding.tv.text = result.data?.getStringExtra("text")
}
}
companion object {
var number : Int = 0
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.tv.setOnClickListener {
val intent = Intent(this, ActivityB::class.java)
startForResult.launch(intent)
}
}
}
If you don't want that onCreate
should be called again when orientation changes. Then in your Manifest you can add configChanges
:
<activity android:name=".MainActivity"
android:configChanges="orientation|screenSize">
Upvotes: 0
Reputation: 11110
You can save the value in onSaveInstanceState()
and use setResult in onRestoreInstanceState()
.
Upvotes: 0