Как я могу вернуться к родительской активности правильно?

У меня есть 2 действия (A и B) в приложении для Android и я использую намерение перейти от действия A к активности B. Использование parent_activity включено:

 <activity
        android:name=".B"
        android:label="B" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.app_name.A" />
  </activity>

Я также использую тему, которая предоставляет кнопку UP.

Итак, после того, как я вызвал активность, BI может использовать UP-кнопку, чтобы вернуться к активности A. Проблема в том, что приложение, похоже, снова вызывает функцию onCreate() для активности A, и это не то поведение, которое мне нужно, Мне нужна операция А, чтобы выглядеть так же, как она выглядела, прежде чем я назвал активность В.

Есть ли способ достичь этого?

Заранее спасибо

EDIT:

Я не писал ни одного кода, чтобы начать действие B из активности A. Я думаю, что он автогенерируется eclipse.

Класс B выглядит следующим образом:

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_b);
    getActionBar().setDisplayHomeAsUpEnabled(true);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_b, menu);
    return true;
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            NavUtils.navigateUpFromSameTask(this);
            return true;
    }
    return super.onOptionsItemSelected(item);
}

Ответ 1

Вы объявили активность A со стандартным launchMode в манифесте Android. Согласно документации, это означает следующее:

Система всегда создает новый экземпляр действия в целевой задача и направляет на нее намерение.

Следовательно, система вынуждена воссоздать активность A (т.е. вызывать onCreate), даже если стек задачи обработан правильно.

Чтобы устранить эту проблему, вам необходимо изменить манифест, добавив в объявление активности A следующий атрибут:

android:launchMode="singleTop"

Примечание. При вызове finish() (как предлагается раньше) работает только, когда вы полностью уверены, что экземпляр операции B завершает жизнь поверх экземпляра активности A. В более сложные рабочие процессы (например, запуск активности B из уведомления), это может быть не так, и вы должны правильно запустить активность A из B.

Ответ 2

Обновленный ответ: Up Navigation Design

Вы должны объявить, какое действие является соответствующим родителем для каждого вида деятельности. Это позволяет системе упростить навигационные шаблоны, такие как Up, потому что система может определять логическую родительскую активность из файла манифеста.

Итак, для этого вам нужно объявить родительскую активность в теге Activity с атрибутом

android:parentActivityName

Как

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

С объявленной таким образом родительской активностью вы можете перейти к соответствующему родительскому элементу, как показано ниже,

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    // Respond to the action bar Up/Home button
    case android.R.id.home:
        NavUtils.navigateUpFromSameTask(this);
        return true;
    }
    return super.onOptionsItemSelected(item);
}

Итак, когда вы вызываете NavUtils.navigateUpFromSameTask(this); этот метод, он завершает текущую активность и запускает (или возобновляет) соответствующую родительскую активность. Если целевая родительская активность находится в стеке возврата задачи, она выводится вперед, как определено FLAG_ACTIVITY_CLEAR_TOP.

И чтобы отобразить кнопку "Вверх", вы должны объявить setDisplayHomeAsUpEnabled():

@Override
public void onCreate(Bundle savedInstanceState) {
    ...
    getActionBar().setDisplayHomeAsUpEnabled(true);
}

Старый ответ: (Без навигации вверх, по умолчанию Back Navigation)

Это произойдет, только если вы снова запустите Activity A из Activity B.

Использование startActivity().

Вместо этого из Activity A запустите Activity B с помощью startActivityForResult() и переопределите onActivtyResult() в Activity A.

Теперь в действии B просто вызовите finish() на кнопке Up. Итак, теперь вы перенаправляетесь на Activity A onActivityResult() без создания Activity A снова.

Ответ 3

У меня была почти такая же настройка, которая привела к такому же нежелательному поведению. Для меня это сработало добавьте следующий атрибут к активности A в Manifest.xml моего приложения:

Android: launchMode = "singleTask"

Для пояснения см. http://www.peachpit.com/articles/article.aspx?p=1874864.

Ответ 4

Хотя старый вопрос, вот еще одно (самое лучшее и лучшее) решение, поскольку все предыдущие ответы не работали для меня, так как я деактивировал активность B из Widget strong > .

public void navigateUp() {
final Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent) || isTaskRoot()) {
    Log.v(logTag, "Recreate back stack");
        TaskStackBuilder.create(this).addNextIntentWithParentStack(upIntent).startActivities();
  } else {
    NavUtils.navigateUpTo(this, upIntent);
  }
}

[fooobar.com/questions/44402/...]

Но также см.: https://speakerdeck.com/jgilfelt/this-way-up-implementing-effective-navigation-on-android

Ответ 5

Лучший способ добиться этого - использовать две вещи: звоните:

NavUtils.navigateUpFromSameTask(this);

Теперь, чтобы это сработало, вам нужно, чтобы ваше состояние манифеста указывало, что активность A имеет родительскую активность B. Родительская активность ничего не нуждается. В версии 4 и выше вы получите хорошую стрелку назад без каких-либо дополнительных усилий (это можно сделать и в более низких версиях, с небольшим кодом, я опишу ниже) Вы можете установить эти данные на вкладке manifest- > application в GUI (прокрутите вниз до названия родительской активности и поместите ее вручную)

Поддержка node:

если вы хотите поддержать версию ниже версии 4, вам также необходимо включить метаданные. щелкните правой кнопкой мыши на активности, add- > meta data, name = android.support.PARENT_ACTIVITY и value = your.full.activity.name

чтобы получить хорошую стрелку в более низких версиях:

getSupportActionBar().setDisplayHomeAsUpEnabled(true);

обратите внимание, что вам понадобится поддержка версии 7 для поддержки этой работы, но это того стоит!

Ответ 6

Я попробовал android:launchMode="singleTask", но это не помогло. Работал для меня с помощью android:launchMode="singleInstance"

Ответ 7

У меня была аналогичная проблема с использованием android 5.0 с именем плохой родительской активности

<activity
        android:name=".DisplayMessageActivity"
        android:label="@string/title_activity_display_message"
        android:parentActivityName=".MainActivity" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.myfirstapp.MainActivity" />
    </activity>

Я удалил com.example.myfirstapp из имени родительской активности и правильно работал

Ответ 8

Добавление в @LorenCK ответа, изменение

NavUtils.navigateUpFromSameTask(this);

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

Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
    TaskStackBuilder.create(this)
            .addNextIntentWithParentStack(upIntent)
            .startActivities();
} else {
    NavUtils.navigateUpTo(this, upIntent);
}

Это запустит новую задачу и запустит родительскую активность Activity, которую вы можете определить в манифесте, как показано ниже в версии Min SDK <= 15

<meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value="com.example.app_name.A" />

Или используя parentActivityName, если его > 15

Ответ 9

Что работало для меня, добавляли:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {
            case android.R.id.home:
                onBackPressed();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public void onBackPressed() {
        finish();
    }

до TheRelevantActivity.java, и теперь он работает как ожидалось

и да, не забудьте добавить:

getSupportActionbar.setDisplayHomeAsUpEnabled(true); в onCreate() метод

Ответ 10

Добавить в свою информацию о манифесте активности с атрибутом

android:launchMode="singleTask"

работает хорошо для меня

Ответ 11

попробуйте следующее:

Intent intent;
@Override
public void onCreate(Bundle savedInstanceState) {
intent = getIntent();   
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_b);
getActionBar().setDisplayHomeAsUpEnabled(true);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_b, menu);
return true;
}  


@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
    case android.R.id.home:
    NavUtils.navigateUpTo(this,intent);
        return true;
}
return super.onOptionsItemSelected(item);
}

Ответ 12

    @Override
public boolean onOptionsItemSelected(MenuItem item) {
   switch (item.getItemId()) {
// Respond to the action bar Up/Home button
    case android.R.id.home:
        finish();
        return true;
}
return super.onOptionsItemSelected(item);

как нажимайте кнопку "Назад"

Ответ 13

Вступление в мой манифест и добавление android:launchMode="singleTop" к активности сделали трюк для меня.

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

Ссылка: android: launchMode

Ответ 14

В классе Java: -

    toolbar = (Toolbar) findViewById(R.id.apptool_bar);
    setSupportActionBar(toolbar);

    getSupportActionBar().setTitle("Snapdeal");

    getSupportActionBar().setHomeButtonEnabled(true);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

В манифесте: -

<activity
            android:name=".SubActivity"
            android:label="@string/title_activity_sub"
            android:theme="@style/AppTheme" >
            <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".MainActivity"></meta-data>
    </activity>

Это поможет вам

Ответ 15

Используйте finish() в действии для возврата в случае события click.