【问题标题】:Launch-Activity onCreate() called again when start another Activity启动另一个 Activity 时再次调用 Launch-Activity onCreate()
【发布时间】:2021-05-11 13:25:44
【问题描述】:

我的 Android 应用通过一个简单的 Activity 启动,并显示一个 ProgressBar。初始化一些数据,然后加载 MainActivity 供用户交互。

问题:

当调用 showMainActivity() 中的 startActivity() 时,会再次调用 InitActivity 中的 onCreate() - 方法。这会导致数据再次被初始化并且 MainActivity 被启动两次。奇怪的是,这并没有以无限循环结束,而是只发生一次。

有谁知道为什么 startActivity() 会导致 InitActivity 的 onCreate() 再次被调用?

代码:

public class InitActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {

//GETS CALLED AGAIN AFTER showMainActivity()

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_init);

    DatabaseInitTask databaseInitTask = new DatabaseInitTask(getApplicationContext(), new DatabaseInitTask.DatabaseInitCallback() {
        @Override
        public void onInitCompleted() {

                    showMainActivity();
            });
        }
    });

    databaseInitTask.execute("");
}

private void showMainActivity() {
    Intent intent = new Intent(getApplicationContext(), MainActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    startActivity(intent);
}
}

清单:

   <activity
        android:name=".Ui.MainActivity"
        android:label="@string/app_name"
        android:windowSoftInputMode="adjustPan">
        <intent-filter>
            <action android:name="android.intent.action.VIEW"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <category android:name="android.intent.category.BROWSABLE"/>
            <data
                android:host="mydomain.com"
                android:scheme="https"/>
        </intent-filter>
    </activity>
    <activity
        android:name=".Ui.InitActivity"
        android:label="@string/app_name"
        android:windowSoftInputMode="adjustPan">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

【问题讨论】:

  • 最简单的修复(不确定是否正确)是检查 savedInstanceState 包是否为空。如果它为空,则意味着正在创建一个新的活动实例。否则,将重新创建现有的活动实例。
  • 似乎两次 onCreate() 都被称为 savedInstanceState 是 null :(
  • 难以置信。你怎么知道会发生这种情况?
  • 我通过 Logcat 记录了这个。并且 onCreate() 被调用了两次,并且两次 saveInstanceState 的时间都是空的。
  • 请添加额外的日志记录,以便您在onCreate() 中记录对象实例ID(记录this 的值)。这将告诉您是否在 Activity 的同一实例上调用了两次 onCreate()(非常值得怀疑),或者是否正在创建 Activity 的 2 个实例。

标签: java android android-activity


【解决方案1】:

您是否对 AndroidManifest 文件进行了更改?如果没有,试试这个

        <activity android:name="com.android.example.sleepcodelab.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

从“MainActivity”活动标签中剪切intent-filter部分,并将其粘贴到“InitActivity”活动标签中。

【讨论】:

  • 将此部分从 AndroidManifest 添加到我的第一篇文章中。一切都和你的代码一样
【解决方案2】:

我已经找到了解决方案。我在这里提出我的解决方案,以防有人遇到类似问题。

问题是我在 MainActivity 中调用了以下函数:

AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);

这导致重新创建完整的活动堆栈(包括 InitActivity)。 InitActivity 的 savedInstanceState 为 null,我无法对其做出反应。

错误的程序流程如下:

App 以 InitActivity 启动 -> 一些数据已初始化 -> InitActivity 启动 MainAcitvity -> MainActivity 调用 setDefaultNightMode 导致 InitActivity 重新启动但 savedInstanceState 为空 -> InitActivity 再次启动 MainAcitvity

这没有以无限循环结束的原因是 MainAcitvity 检查夜间模式是否已正确设置,并且仅在需要更改设置时才调用setDefaultNightMode。

我是如何解决的:

我将setDefaultNightMode 移至 InitActivity。这仍然会导致 onCreate 在 InitActivity 中被第二次调用,但这次 savedInstanceState 不为空,我可以使用 savedInstanceState 来防止 MainActivity 再次启动。

我不完全理解为什么 savedInstanceState 不再为 null 但它现在可以工作了。

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_init);

    if(savedInstanceState == null) {
        AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
    } else
    {
    DatabaseInitTask databaseInitTask = new DatabaseInitTask(getApplicationContext(), new DatabaseInitTask.DatabaseInitCallback() {
        @Override
        public void onInitCompleted() {

                    showMainActivity();
                }
            });
        }
    });

    databaseInitTask.execute("");
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-11
    • 2014-05-15
    • 1970-01-01
    • 2011-10-17
    • 1970-01-01
    • 2016-05-26
    相关资源
    最近更新 更多