onActivityResult в java - как обработать BackHandler из Composable?
Вводные: Имеется сложный проект на java, переписываемый в данный момент модульно на kotlin с использованием jetpack compose (в частности Composable функций). Старая реализация передачи extra параметров между разными activity является типичной (через intent):
MainActivity (java):
button.setOnClickListener(v -> {
startActivityForResult(new Intent(MainActivity.this, SecondActivity.class), 1234);
});
.....
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1234 && resultCode == RESULT_OK) {
//TODO Здесь какие-то действия (например получение инта)
}
}
SecondActivity (java):
int intPosition = 7
backButton.setOnClickListener(view -> {
Intent intent = new Intent();
intent.putExtra("result", intPosition);
setResult(RESULT_OK, intent);
finish();
});
Однако новая реализация с переходом на Composable подразумевает использование BackHandler & OnBackPressedDispatcher, далее пример:
Second Activity (kotlin with @Composable):
class SecondActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
PatternPager()
}
}
}
}
@Composable
fun PatternPager() {
val onBackPressedDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher
val onBackToActivity = {
println("back pressed")
scope.launch {
awaitFrame()
onBackPressedDispatcher?.onBackPressed()
}
}
Box(...) {
Row(...) {
...
Button(
onClick = {
scope.launch {
//TODO Здесь логика перехода
onBackToActivity()
}
}
}
}
Вопрос заключается в том, какие изменения необходимо провести в файле MainActivity.java, чтобы принять изменения из @Composable функции PatternPager() по аналогии с onActivityResult, а так же как отправлять изменения из @Composable в java.
Переход уже реализован, необходимо только передать extras. Задача непростая, так как MainActivity необходимо сохранить в java формате.
Прошу помочь и высказать свои предложения / предположения людей, столкнувшихся с частичной миграцией проекта с java на kotlin.
Ответы (1 шт):
Потратив несколько дней и +- изучив матчасть пришёл к следующему решению:
Замена @Deprecated startActivityForResult на более современный ActivityResultLauncher в java экране
Замена не оправдавшего надежды (а может я просто не научился) onBackPressedDispatcher на activity в @Composable внутри экрана на kotlin
Далее привожу примеры кода в измененных экранах MainActivity.java и SecondActivity.Kt соответственно.
MainActivity.java:
button.setOnClickListener(v -> {
Intent intent = new Intent(this, SecondActivity.class)
activityResultLaunch(intent);
});
.....
ActivityResultLauncher<Intent> activityResultLaunch = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
activityResult -> {
if (activityResult.getResultCode() == Activity.RESULT_OK) {
switch(activityResult.getData().getIntExtra("requestCode", 0)) {
case 1234:
//TODO Здесь какие-то действия (например получение инта)
break;
default:
//TODO Здесь ветка стандартных действий
break;
}
}
}
.....
SecondActivity.Kt:
class SecondActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
PatternPager()
}
}
}
}
@Composable
fun PatternPager() {
val activity = (LocalLifecycleOwner.current as ComponentActivity)
Box(...) {
Row(...) {
...
Button(
onClick = {
scope.launch {
//TODO Здесь логика перехода
val intent = Intent()
intent.putExtra("result", serializableModel)
intent.putExtra("requestCode", 1234)
activity.setResult(RESULT_OK, intent)
activity.finish()
}
}
}
Button(
onClick = {
scope.launch {
//TODO Здесь перехода без результата (отмена)
activity.setResult(RESULT_CANCELED)
activity.finish()
}
}
}
}
Проблема решена.