当启动一个对话框活动并重新创建活动时,OnActivityResult未被调用

4
我有两个活动,A 和 B。通过调用 startActivityForResult(),A 启动了 B。B 的主题为@android:style/Theme.Dialog
因此,B 显示在 A 的上面,但 A 仍然可见(因为 B 是一个对话框)。
当启动这两个活动时,我通过切换到另一个任务然后返回来强制重新创建它们(我在 Android 开发者设置中启用了“不保留活动”选项。我发现当我返回到我的任务时,A 和 B 的 OnCreate 方法被调用)。
当我在 Activity B 中单击按钮时,它调用 setResult()finish(),但是 onActivityResult() 在 A 上未被调用
问题出现在以下情况下:
  • 如果我不强制重新创建活动。
或者
  • 如果我从 Activity B 中删除对话框主题。
我在安装有Android 9的Google Pixel上测试了这个问题。
这是我用于测试的代码(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()都被调用 - 因此两个活动都是新启动的,因此Activity B不是通过startActivityForResult()创建的 - 因此在从Activity B返回A时,它不会调用Activity A的onActivityResult()。 - Raj
这对我来说听起来像是一个bug。我使用原生的Android无法重现这种行为。 - Ben P.
嗯,我想问一下关于你这个任务的事情,它是做什么的?我的意思是说,你通过这个任务实现了什么? - FreakyAli
你如何通过切换到另一个任务并返回来强制重新创建?为什么不想保留这些活动? - tynn
1个回答

0
我会尝试解释这里发生了什么。不保留活动用于模拟设备上的低内存行为,以便当活动进入后台状态(onPause、onStop)并由于内存耗尽而被杀死时,它将保存所需的状态。大多数视图状态由Android操作系统本身保存,并负责在活动返回前台时恢复它们。
现在根据您的情况,在普通的Vanilla Android中启动B活动时,主题似乎没有任何问题。它将暂停和停止A活动,因为它不是DialogActivity。它只有一个对话框主题。如果Xamarin处理对话框主题不同,则可能存在问题,您应该与Xamarin进行验证。
现在,当您将B活动放入后台(onPause、onStop)时,它也将被杀死,因为您已经开启了“不保留活动”选项。但是,恢复所有活动(即B和之前的所有活动以及正确的视图状态)是Android操作系统的工作。即使您在恢复状态时看到A活动被创建,您也会看到在Bundle中保存的所有状态都得到恢复(ActivityA的onCreate参数)。
这种情况发生的另一个可能性可能是设备特定的。如前所述,纯安卓系统上不会出现这种情况,但制造商(小米、三星)对安卓系统进行了修改,这很可能是你的问题所在。最好先为纯安卓开发应用程序,然后针对每个制造商进行代码定制。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接