ActionBar向上导航重新创建父活动而不是onResume

时间:2013-03-21 23:04:30

标签: android android-actionbar

我正在使用Up Navigation推荐的方法,我的代码如下所示:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            Intent h = new Intent(ShowDetailsActivity.this, MainActivity.class);
            h.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(h);
            return true;
        default: return super.onOptionsItemSelected(item);
    }
}

以下是用例:

  1. 我启动了我的应用程序“MainActivity”
  2. 我点击一个按钮转到“ShowDetailsActivity”
  3. 我点击了UP ActionBar导航
  4. 问题是在我点击UP之后,MainActivity再次点击它的onCreate()方法而失去所有状态而不是从典型的onResume()开始,就像我刚刚从ShowDetailsActivity调用“finish()”一样。为什么?它是如何工作的,这是Android重新创建使用“向上”导航方法导航到的所有活动的预期行为?如果我点击后退按钮,我会得到预期的onResume生命周期。

    如果Android“正确”不存在,这是我的解决方案:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                Intent upIntent = new Intent(this, MainActivity.class);
                if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
                    NavUtils.navigateUpTo(this, upIntent);
                    finish();
                } else {
                    finish();
                }
                return true;
            default: return super.onOptionsItemSelected(item);
        }
    }
    

6 个答案:

答案 0 :(得分:84)

将以下内容添加到清单文件

中的父活动
android:launchMode="singleTop"

关于此answer

答案 1 :(得分:56)

原因,使用向上导航时重新创建的活动是,如果您没有指定其他模式,那么Android会使用标准启动模式。这意味着

  

“系统始终在中创建活动的新实例   目标任务“

因此重新创建活动(参见文档here)。

解决方案将声明MainActivity的启动模式为

android:launchMode="singleTop"
<{1>}中的

(应始终与AndroidManifest.xml一起使用

您可以将FLAG_ACTIVITY_SINGLE_TOP添加到您的意图标记中,告诉活动它不应该重新创建,如果它位于后端堆栈上,例如

Intent.FLAG_ACTIVITY_CLEAR_TOP

答案 2 :(得分:11)

此代码对我有用:

Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
    // This activity is NOT part of this app's task, so create a new task
    // when navigating up, with a synthesized back stack.
    TaskStackBuilder.create(this)
        // Add all of this activity's parents to the back stack
        .addNextIntentWithParentStack(upIntent)
        // Navigate up to the closest parent
        .startActivities();
} else {
    // This activity is part of this app's task, so simply
    // navigate up to the logical parent activity.
    upIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    NavUtils.navigateUpTo(this, upIntent);
}

return true;

不需要finish()调用。

答案 3 :(得分:3)

从Android 4.1(API级别16)开始,您可以通过在元素中指定android:parentActivityName属性来声明每个活动的逻辑父级。 如果您的应用支持Android 4.0及更低版本,请在您的应用中添加支持库,并在其中添加元素。然后将父活动指定为android.support.PARENT_ACTIVITY的值,与android:parentActivityName属性匹配。

<application ... >
...
<!-- The main/home activity (it has no parent activity) -->
<activity
    android:name="com.example.myfirstapp.MainActivity" ...>
    ...
</activity>
<!-- A child of the main activity -->
<activity
    android:name="com.example.myfirstapp.DisplayMessageActivity"
    android:label="@string/title_activity_display_message"
    android:parentActivityName="com.example.myfirstapp.MainActivity" >
    <!-- Parent activity meta-data to support 4.0 and lower -->
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value="com.example.myfirstapp.MainActivity" />
</activity>

如果父活动具有启动模式,或者up意图包含FLAG_ACTIVITY_CLEAR_TOP,则父活动将被带到堆栈顶部,并通过其onNewIntent()方法接收意图。

<activity
        android:launchMode="singleTop"
        android:name="com.example.myfirstapp.MainActivity">

    </activity>

在上面代码“SingleTop”中,还可以创建“singleTop”活动的新实例来处理新意图。但是,如果目标任务已经在其堆栈顶部具有活动的现有实例,则该实例将接收新意图(在onNewIntent()调用中);未创建新实例。

For Detail Documentation Click Here

要在用户按下应用图标时向上导航,您可以使用NavUtils类的静态方法navigateUpFromSameTask()。 对于那阅读上面链接中给出的文档。

答案 4 :(得分:1)

对我有用的(我也认为最干净的)是将活动重新排序到前面。如果它在堆栈中不存在,它将在你“向上导航”时创建。

Intent upIntent = NavUtils.getParentActivityIntent(this);
upIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(upIntent);
finish();
return true;

答案 5 :(得分:0)

你只需要回去,而不是再次创建活动。

public ActionResult LogIn(Models.Entity.UserUtil utilizator)
{
    if (ModelState.IsValid)
    {
        var v = db.UserUtils.Where(a => a.UserEmail.Equals(utilizator.UserEmail) && a.UserPassword.Equals(utilizator.UserPassword)).FirstOrDefault();
        if (v != null)
        {
            Session["LoggedUsername"] = v.UserEmail.ToString();
            Session["cod_ap"] = v.cod_ap.ToString();
            //Session["LoggedUserPassword"] = v.UserPassword.ToString();

            if (Session["cod_ap"].ToString() == "11111")
            {
                return RedirectToAction("AdminLogin");
            }
            else
            {
                return RedirectToAction("AfterLogin");
            }

        }
    }
    return View();
}