Как вернуть результат "естественным образом", когда вызываемая вызываемая активность завершается?

Что работает 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 небольшую часть большого объекта (адрес доставки), вы всегда можете сохранить любые изменения внутри меньшего действия, потому что пользователь может отменить все изменения, отменив большую активность.