OnActivityResult не вызывается при запуске диалогового действия и воссоздания действий

У меня есть два вида деятельности: A и B. A начинает B с вызова startActivityForResult(). B имеет тему @android:style/Theme.Dialog.

Таким образом, B отображается «поверх» A, но A все еще отображается (поскольку B является диалоговым окном).

Когда запускаются оба действия, я принудительно переключаюсь на другую задачу и обратно (я включил опцию «Не сохранять действия» в настройках разработчика Android. Я вижу, что OnCreate вызывается в A и B, когда я возвращаюсь к своей задаче .)

Когда я нажимаю кнопку в действии B, он вызывает setResult() и finish(), но onActivityResult()не вызывается на A.

Проблема не возникает

  • если я не заставлю воссоздать деятельность

или

  • если я удалю тему диалога из Activity B.

Я тестировал это на Google Pixel с Android 9.

Это ожидаемое поведение или ошибка в Android?


Это код, который я использовал для тестирования (Xamarin Android):

[Activity(Label = "@string/app_name")]
public class ActivityA : Activity
{

    protected override void OnCreate(Bundle savedInstanceState)
    {
        Kp2aLog.Log("OnCreate A");
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.yubichall_test);

        {
            FindViewById<Button>(Resource.Id.btn_yubichall).Text = "Start B";
            FindViewById<Button>(Resource.Id.btn_yubichall).Click += (sender, args) =>
            {

                var chalIntent = new Intent(this, typeof(ActivityB));

                StartActivityForResult(chalIntent, 123);

            };
        }


    }

    protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
    {
        base.OnActivityResult(requestCode, resultCode, data);
        Android.Util.Log.Debug("KP2A", "OnActivityResult A: " + requestCode);

    }
}
[Activity(Label = "@string/app_name", Theme = "@android:style/Theme.Dialog")]
public class ActivityB : Activity
{

    protected override void OnCreate(Bundle savedInstanceState)
    {
        Kp2aLog.Log("OnCreate B");
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.yubichall_test);

        FindViewById<Button>(Resource.Id.btn_yubichall).Text = "Return result to A";

        {
            FindViewById<Button>(Resource.Id.btn_yubichall).Click += (sender, args) =>
            {
                SetResult(Result.Ok);
                Finish();

            };
        }


    }
}

где раскладка yubicall_test

    <?xml version = "1.0" encoding = "utf-8" ?>
<LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
              android:layout_width = "fill_parent"
              android:orientation = "vertical"
              android:layout_height = "wrap_content">
  <Button android:id = "@+id/btn_yubichall"
          android:layout_width = "wrap_content"
          android:layout_height = "wrap_content"
          android:text = "yubi challenge"
  />

  <TextView
    android:id = "@+id/text_result"
    android:layout_width = "wrap_content"
    android:layout_height = "wrap_content"
  />

</LinearLayout>

Я считаю, что он работает правильно, как вы упомянули, возвращаясь из другой задачи, вызываются onCreate () обоих действий - поэтому оба действия запускаются заново, поэтому действие B не создается через startActivityForResult () - поэтому он не будет вызов onActivityResult () действия A при переходе от действия B к A.

Raj 04.12.2018 17:09

Для меня это звучит как ошибка. Мне не удалось воспроизвести это поведение с помощью ванильного Android.

Ben P. 04.12.2018 20:31

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

FreakyAli 05.12.2018 07:29

Как заставить отдых, переключившись на другую задачу и обратно? И почему вы не хотите продолжать занятия?

tynn 05.12.2018 17:07
4
4
513
1

Ответы 1

Я постараюсь объяснить, что здесь происходит. Не сохранять активность используется для имитации нехватки памяти на устройстве, поэтому, когда активность переходит в фоновое состояние (onPause, onStop) и прекращается из-за гашения памяти, она сохранит необходимое состояние. Большинство состояний просмотра сохраняются самой ОС Android и отвечают за их восстановление, когда активность возвращается на передний план.

Теперь, согласно вашему сценарию, тема, похоже, не создает каких-либо проблем в обычном ванильном android при запуске активности B. Она приостанавливает и останавливает действие A, поскольку это не DialogActivity. Это просто тема диалога. Вы должны проверить это с помощью Xamarin, если он по-другому обрабатывает тему диалога, это может быть проблемой.

Теперь, когда вы помещаете Activity B в фоновый режим (onPause, onStop), он также будет убит, поскольку у вас есть Dont keep activity. Но восстановление всех действий (то есть B и всего до этого с правильными состояниями просмотра) - это задача ОС Android. Даже если вы видите создание Activity A при восстановлении состояния, вы увидите, что все состояния, сохраненные в пакете, восстанавливаются (параметр onCreate для ActivityA).

Другая возможность этого может быть связана с конкретным устройством. Как обсуждалось ранее, этого не происходит на Plain Android, но производители (Xiaomi, Samsung) вносят изменения в ОС Android, и это вполне может быть вашей проблемой. Хорошая идея - сначала разработать приложение для простого Android, а затем настроить код для каждого производителя.

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