Как передать результат MethodChannel новому действию?

коллеги-энтузиасты, профи и будущие друзья Flutter. Я действительно ломал голову, пытаясь передать MethodChannel.Result из MainActivity новому действию (чтобы обработать обработчик результата после выполнения некоторой работы там).

В iOS я вставил FlutterResult в структуру с другими соответствующими значениями и передал их в новый ViewController, после чего успешно запустил обработчик результатов оттуда.

Как мне это сделать в Android? Поскольку результат не сериализуем, я не могу добавить его в намерение.

В моей MainActivity я запускаю setMethodCallHandler, а в правильном случае call.method я создаю новое намерение и запускаю его. Я успешно добавляю и извлекаю значения String в новом действии, но это тот результат Flutter, который мне нужно пропустить.

Какой рекомендуемый способ добиться этого? Я ошибаюсь?

Я спрашиваю, делаю ли я это неправильно, потому что, когда я завершаю () это новое действие, появляется черный экран продолжительностью полсекунды, который заменяет экран, когда действие закрывается.

Не уверен, что это важно, но пишу на Котлине. Я был бы рад услышать любые рекомендации по Java.

Спасибо всем заранее.

У меня такая же проблема с IOS. Не могли бы вы добавить код iOS?

Jigar Fumakiya 23.04.2021 08:19
0
1
1 571
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Без некоторого дополнительного контекста о том, что именно вы делаете в новом действии, немного сложно сказать, почему у вас будет черный экран. Теоретически активность флаттера должна продолжаться и должна появиться, когда вы закончите новую активность - если только вы не делаете что-то, блокирующее поток пользовательского интерфейса.

Однако для передачи result вы хотите сохранить ссылку на обработчик result, где бы вы ни получали сообщение от flutter, и использовать метод Android startActivityForResult. См. Документацию по Android на получение результата от деятельности. Ваша «рабочая» активность должна делать все, что ей нужно, а затем передавать результат обратно, вызывая setResult до завершения. Данные, которые вы передаете, должны быть сериализуемыми.

Есть небольшая добавленная морщина - вы не обязательно работаете здесь со своей собственной деятельностью (если вы все равно пишете плагин). В этом случае вам необходимо реализовать ActivityResultListener и вызвать registrar.addActivityResultListener в функции registerWith вашего плагина. Если вы просто делаете это в приложении, вы можете просто переопределить onActivityResult - просто обязательно вызовите super, иначе вы можете сломать другие плагины flutter.

Есть еще одно возможное решение этой проблемы с различными уровнями взлома в зависимости от того, насколько глубоко вы хотите быть. Решение состоит в том, чтобы просто использовать Singleton или Global для хранения того, что вам нужно между действиями. Для всех, кто это читает - я не поддерживаю это, я просто предлагаю альтернативу. Есть предостережения, связанные с этим - среди них то, что глобальные объекты и, в меньшей степени, синглтоны считаются плохой идеей по многим причинам, в том числе из-за ремонтопригодности кода. Если вам абсолютно необходимо пойти по этому пути, я предлагаю использовать шаблон реестра, а не простой синглтон, т. Е. Вы создаете ключ, который можно сериализовать, и сохраняете Result по существу в глобальной / одноэлементной карте с помощью ключа, передайте ключ новому activity, затем в новом действии получите значение с этим ключом (и обязательно удалите объект с карты).

Обратите внимание, что параметр global / singleton / registry не будет работать должным образом, если приложение остановлено Android, поскольку действие может быть воссоздано из его намерения, но объект в памяти может не сохраняться. Опять же - обратный вызов флаттера в любом случае не будет сохраняться, так что этот вопрос в любом случае может быть спорным.

Если вы все еще видите черный экран после завершения нового действия, это больше похоже на ошибку или что-то, связанное с реализацией вашего нового действия, чем на проблему флаттера.

Спасибо, Морган. Я разработчик iOS, поэтому я не знал о функциях, которые вы упомянули! // На черном экране мне нужно будет найти устройство и протестировать его, потому что сейчас я работаю только с смоделированным устройством Android на компьютере. Может быть, это то, что вызывает это? Я не делаю ничего особенного. Просто начинайте новое намерение с двумя текстовыми представлениями, а FAB просто запускает 'finish ()' после нажатия. Когда действие прекращается вниз, за ​​ним остается черный экран, который задерживается до того, как снова появляется экран Flutter.

baQer 07.07.2018 02:55

Я посмотрю, смогу ли я в какой-то момент воспроизвести это (или, если ваше приложение имеет открытый исходный код, я могу просто попробовать = D). Определенно есть вещи, которые не работают на эмуляторе так же хорошо, как на реальном устройстве, хотя, надеюсь, это то, что вы видите.

rmtmckenzie 07.07.2018 03:14

Морган, еще раз спасибо. Просто написал код, используя startActivityForResult, и я смог успешно передать сериализованные данные обратно в приложение Flutter. Также на физическом устройстве завершение собственной активности - это не черный экран, который неловко удерживается в фоновом режиме в течение миллисекунд, но в то же время начало и завершение - это очень уродливый, а не плавный переход. У вас есть какие-нибудь советы, как сделать здесь переходы более плавными? Я попытался переопределить вызов «finish» и запустить функцию overridePendingTransition, но студия Android утверждает, что все значения анимации являются частными.

baQer 08.07.2018 04:37

Другие вопросы по теме