Используя startActivityForResult, как получить requestCode в дочерней активности?

88

У меня есть четыре действия, скажем, A, B, C и D. Моя ситуация: A запустит действие B с помощью startActivityForResult.

startActivityForResult(new Intent(this,B.class),ONE);

В другой ситуации я буду B с другой ситуацией. нравиться

 startActivityForResult(new Intent(this,B.class),TWO);

В B мне нужно вызвать C или D в зависимости от requestCode. Т.е. если ОДИН нужно запустить C, иначе D.
Поэтому мне нужно знать, как проверить requestCode в дочернем Activity (здесь B).
Другими словами, я хочу получить код запроса, с которого было запущено действие B.

Джитин
источник

Ответы:

140

Вы можете передать код запроса, добавив доп.

intent.putExtra("requestCode", requestCode);   

Или , если вы использовали startActivityForResultмного раз, то лучше , чем редактирование каждого, вы можете в вашем , добавить вам код там , как это overridestartActivityForResultActivity

@Override
    public void startActivityForResult(Intent intent, int requestCode) {
        intent.putExtra("requestCode", requestCode);
        super.startActivityForResult(intent, requestCode);
    }

Так что нет необходимости редактировать все ваши startActivityForResult
Надеюсь, это помогло вам

Лабиб Панампуллан
источник
51
Неужели дочерняя активность не может получить код запроса?
i_am_jorf
1
До сих пор, насколько мне известно, другого пути не было.
Labeeb Panampullan
17
Интересно то же самое - это одна из тех вещей в API Android, которая не имеет никакого логического смысла.
Артем Русаковский
9
startActivityForResult можно использовать для запуска действий в других приложениях, requestCode - это личное дело вашего приложения. В этом свете логично, что Intent не имеет такого метода, и правильный подход - это setAction, сообщающий, что именно вы хотите, чтобы Activity делала.
Maciej Beimcik
28

Код запроса не передается в запущенное действие автоматически, потому что ему не нужно (и не должно) знать это значение. Ему нужно только знать, что делать, а не откуда это было начато.

На самом деле запуск действия - это просто еще одна форма вызова метода. Когда вы вызываете метод, вы получаете результат синхронно (прямо там, где вы сделали вызов). В этом случае вы передаете только ту информацию, которая необходима методу для работы. Вы не говорите, откуда вы его вызывали.

Запуск действия - это асинхронный аналог вызова метода, и в этом случае вы получаете результат в специальном методе onActivityResult (). В этом методе вам нужно знать, что делать с только что полученным результатом, и у вас есть код запроса для этого.

Чтобы было немного понятнее, почему не рекомендуется передавать код запроса в качестве параметра, рассмотрим пример действия, в котором показан продукт, который вы можете купить. В этом действии есть две кнопки с пометками «Купить» и «Войти» (так как вы в настоящее время не авторизованы). Нажатие «Вход» запустит действие под названием «Вход», которое попытается войти в систему, используя предоставленную информацию. Нажатие кнопки «Купить» сначала запустит ту же операцию «Вход», и, если вход был успешным, запустит действие покупки.

Теперь кнопка «Войти» использует код запроса 1 для начала действия входа в систему, но кнопка «Купить» не может использовать тот же код запроса, поскольку в случае успешного входа в систему ей придется делать что-то другое. Итак, кнопка «Купить» использует код запроса 2.

В действии «Вход в систему» ​​вы можете получить два разных кода запроса в зависимости от того, откуда он был вызван, но вам нужно будет выполнить ту же процедуру.

Итак, если вы передадите код запроса в качестве параметра, вы получите код, который должен делать то же самое для пары разных кодов запроса, например:

if (requestCode == LOGIN || requestCode == BUY) {
    // ...
} else ...

В итоге вы также сохраните константы кода запроса в центральном месте, например, в классе с именем RequestCodes.

Короче говоря, код запроса должен использоваться только для решения, что делать с полученным результатом. Таким образом, вы получите более модульный, более простой в обслуживании и более простой для расширения код.

Сабольч Береч
источник
1
Что, если это своего рода «менеджер», и вы хотите, чтобы код запроса «сохранял» определенное значение (значение, сохраненное в дополнительных функциях). Другой код запроса, который будет «извлекать» значение (и возвращать его в дополнительных функциях), но в рамках этого действия они также могут в целом управлять сохраненными значениями, такими как переименование, редактирование, удаление и т. Д. Что вы думаете по поводу чего-то подобного? Я думаю, это предотвратит дублирование кода / действий для выполнения тех же действий.
JRomero
@ J.Romero Не делай этого, это только усложнит ситуацию. Просто поместите эту функциональность в класс (служебный / одиночный). Вы также можете посмотреть на Handler and Service
Szabolcs Berecz
3
Szabolcs Дочернему действию, даже если ему «не нужно знать это значение», может потребоваться передать значение следующему действию в цепочке. Как ни странно, для этого нам нужно написать более избыточный код. Для чего-то, что нам не нужно знать так много, как мы получаем больше лекций, чтобы прочитать о том, чего нам не следует делать.
user250343 08
Я не понимаю, как это иллюстрирует, почему дочернему действию следует отказать в доступе к коду запроса. Я даже не уверен, почему доступ к коду запроса может быть необходим в вашем конкретном примере, учитывая, что вызовы покупки и входа в любом случае относятся к двум отдельным действиям.
Дражен Беловук
1
@EvanR. возможно, лучшей архитектурой было бы подклассифицировать «основное» действие элемента в отдельные действия добавления / редактирования. Таким образом, повторное использование кода минимально, но каждое действие можно запускать независимо.
Дэйн Пауэлл,
11

Я закончил тем, что использовал настраиваемое действие Intent, чтобы передать такую ​​информацию запускающей Activity.

protected static final String ACTION_DO_C = "do_c";
protected static final String ACTION_DO_D = "do_d";

Тогда вы бы сказали:

final Intent intent = new Intent(this,B.class)
intent.setAction(ACTION_DO_C);
startActivityForResult(intent,ONE);

А в Activity Bвы легко получаете действие:

getIntent().getAction();
Марсель Бро
источник
работает как шарм, действительно лучший ответ. Благодарю.
YvesLeBorg
0

Вы можете использовать getCallingActivity (), чтобы получить действие, которое запустило текущее действие и которое получит значение результата с кодом ответа в конце.

Моаз Рашад
источник