Как вернуть результат "естественным образом", когда вызываемая вызываемая активность завершается?
Что работает Fine
У меня есть 2 действия в моем приложении. Первая активность вызывает вторую результативность результатов.
Второе действие показывает новый макет и позволяет пользователю выполнять определенные действия. Существует кнопка "ОК" . Когда пользователь нажимает эту кнопку, вторая активность завершается, и пользователь возвращается к первой активности.
Под капотом первая активность вызывает вторую активность:
Intent intent = new Intent(this, NextAct.class);
intent.putExtra("input", input);
this.startActivityForResult(intent, 99);
Нажмите кнопку "ОК" , вторая активность возвращается с результатом следующим образом:
Intent intent = new Intent();
intent.putExtra("output", output);
setResult(RESULT_OK, intent);
finish();
После этого первая операция onActivityResult вызывается с результатами успешно:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// requestCode is 99
// resultCode is -1
// data holds my output
}
Над настройкой работает отлично
Что не работает
Теперь у меня было простое требование, я хотел, чтобы пользователь закрыл второе действие не с помощью кнопки "ОК" , но естественным образом с кнопкой "ОБНОВЛЕНИЕ ОБСЛУЖИВАНИЯ".
Я попытался переместить логику setResult в onStop и onDestroy методы второй активности, но оказалось, что onActivityResult первой активности вызывается перед onStop или onDestroy методами второй активности и в результате setResult логика не получает возможности запускать на всех.
Затем я попытался переместить логику setResult в метод onPause второй активности, подобный этому
protected void onPause() {
super.onPause();
Intent intent = new Intent();
intent.putExtra("output", output);
setResult(RESULT_OK, intent);
//finish(); enabling or disabling this does not work
}
Но хотя onPause вызывается задолго до того, как функция onActivityResult и setResult работает правильно, все же я получаю все значения null в onActivityResult
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// requestCode is 99
// resultCode is 0
// data comes as null
}
Мне нужно знать, почему это происходит, и если onResume не является подходящим местом для установки логики setResult, что является самым естественным способом сделать это?
Большое спасибо.
Ответы
Ответ 1
Теперь у меня было простое требование, я хотел, чтобы пользователь закрыл второе действие не с помощью кнопки "ОК" , но естественным образом с кнопкой "ОБНОВЛЕНИЕ ОБСЛУЖИВАНИЯ".
Это обычно не является "естественным" для сценария startActivityForResult()
. Кнопка BACK должна позволить пользователю сказать вам: "Нет, это не нормально" (т.е. Отменить).
Это не означает, что вы обязательно должны иметь кнопку OK. Например, если NextAct
был ListActivity
, типичным шаблоном является щелчок по элементу списка, который будет считаться "ОК" (т.е. Вызов setResult()
и finish()
от onListItemClick()
), а BACK означает "Я действительно не хотел запускать NextAct
, извините".
Мне нужно знать, почему это происходит
Вы вызываете setResult()
слишком поздно. Если пользователь нажимает BACK, к моменту onPause()
результат (RESULT_CANCELED
) уже определен.
если onResume не является подходящим местом для установки логики setResult
onResume()
не будет подходящим местом для "установки логики setResult"
Какой самый естественный способ сделать это?
Возможно, что у вас есть кнопка OK, это "самый естественный способ сделать это".
Однако, если по какой-то странной причине вы действительно хотите, чтобы кнопка BACK означала "ОК" , переопределите onBackPressed()
и вызовите setResult()
там, перед тем как привязать ее к суперклассу с помощью super.onBackPressed()
.
Ответ 2
Лучший способ, который я нашел, - переопределить метод finish():
@Override
public void finish() {
Intent data = new Intent();
data.putExtra(INTENT_PARAM_OPTIONS, options);
setResult(RESULT_OK, data);
super.finish();
}
В этом случае ваша активность всегда будет возвращать данные, даже если пользователь нажимает кнопку "Назад" (или кнопку "вверх" ).
И я думаю, что это совершенно естественно сделать в некоторых обстоятельствах. Если у вас есть активность, которая предназначена для редактирования одного большого объекта (например, порядка доставки) и меньшей активности внутри этого действия, которая изменяет 1 небольшую часть большого объекта (адрес доставки), вы всегда можете сохранить любые изменения внутри меньшего действия, потому что пользователь может отменить все изменения, отменив большую активность.
Ответ 3
Вы можете попробовать переопределить onBackPressed или onKeyDown и setResult (RESULT_OK, намерение).