Закрыть приложение и запустить домашний экран на Android

У меня есть два разных вида деятельности. Первый запускает второй. Во втором действии я вызываю System.exit(0), чтобы заставить приложение закрыться, но первое действие автоматически отображается вместо приложения, возвращающегося на главный экран. Как я могу избежать этого и заставить приложение вернуться на главный экран?

Ответ 1

Вы действительно должны думать о том, чтобы не выйти из приложения. Это не то, как обычно работают приложения Android.

Ответ 2

Короткий ответ: moveTaskToBack(true) на Activity вместо System.exit(). Это скроет ваше приложение, пока пользователь не захочет его использовать.

Более длинный ответ начинается с другого вопроса: почему вы хотите убить ваше приложение?

ОС Android управляет управлением памятью и процессами и так далее, поэтому мой совет просто позволяет Android беспокоиться об этом для вас. Если пользователь хочет покинуть ваше приложение, он может нажать кнопку "Домой", и ваше приложение будет эффективно исчезать. Если телефону потребуется больше памяти, тогда ОС прекратит ваше приложение.

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

Итак, если вы хотите скрыть свой вызов приложения moveTaskToBack() и позволить Android решить, когда его убить.

Ответ 3

Самый простой способ для достижения этого приведен ниже (без влияния на управление встроенной памятью Android. В этом нет процесса убийства).

  • Запустите действие с использованием этого намерения:

    Intent intent = new Intent(this, FinActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(intent);
    finish();
    
  • В целевой активности FinActivity.class завершите вызов() в onCreate.

Разработанные шаги:

  • Вы создаете намерение, которое удаляет все другие действия (FLAG_ACTIVITY_CLEAR_TOP) и удаляет текущую активность.

  • Активность уничтожает себя. Альтернативой является то, что вы можете сделать заставку в finActivity. Это необязательно.

Ответ 4

У Android есть механизм, позволяющий безопасно закрыть приложение в своей документации. В последнем действии, которое вышло (обычно это основное действие, которое впервые появилось при запуске приложения), просто поместите пару строк в метод onDestroy(). Вызов System.runFinalizersOnExit(true) гарантирует, что все объекты будут завершены, а мусор будет собран, когда приложение завершит работу. Например:

public void onDestroy() {
    super.onDestroy();

    /*
     * Notify the system to finalize and collect all objects of the
     * application on exit so that the process running the application can
     * be killed by the system without causing issues. NOTE: If this is set
     * to true then the process will not be killed until all of its threads
     * have closed.
     */
    System.runFinalizersOnExit(true);

    /*
     * Force the system to close the application down completely instead of
     * retaining it in the background. The process that runs the application
     * will be killed. The application will be completely created as a new
     * application in a new process if the user starts the application
     * again.
     */
    System.exit(0);
}

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

Ответ 5

Вы также можете указать noHistory = "true" в теге для первой активности или завершить первое действие, как только вы начнете второй (как сказал Дэвид).

AFAIK, "force close" убивает процесс, в котором размещается JVM, в котором выполняется ваше приложение, и System.exit() завершает запуск JVM вашего экземпляра приложения. Обе формы являются резкими окончаниями и не рекомендуются для нормального потока приложения.

Подобно тому, как исключения для покрытия логических потоков, которые может выполнять программа, нецелесообразны.

Ответ 6

Я использую этот метод для закрытия Activity!

public static void closeAllBelowActivities(Activity current) {
    boolean flag = true;
    Activity below = current.getParent();
    if (below == null)
        return;
    System.out.println("Below Parent: " + below.getClass());
    while (flag) {
        Activity temp = below;
        try {
            below = temp.getParent();
            temp.finish();
        } catch (Exception e) {
            flag = false;
        }
    }
}

Ответ 7

Когда вы запускаете второе действие, finish() первый сразу:

startActivity(new Intent(...));
finish();

Ответ 8

android.os.Process.killProcess(android.os.Process.myPid()); отлично работает, но рекомендуется, чтобы платформа Android беспокоилась об управлении памятью: -)

Ответ 9

Используйте метод finish. Это более простой и простой метод.

this.finish();

Ответ 10

Я использую это:

1) Родительская активность вызывает вторичную активность с помощью метода "startActivityForResult"

2) При вторичной активности при закрытии:

int exitCode = 1; // Select the number you want
setResult(exitCode);
finish();

3) И в родительской активности переопределить метод "onActivityResult":

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    int exitCode = 1;
    if(resultCode == exitCode) {
        super.setResult(exitCode); // use this if you have more than 2 activities
        finish();
    }
}

Это отлично работает для меня.

Ответ 11

Вы не можете использовать System.exit(), это небезопасно.

Вы можете сделать это: Process.killProcess(Process.myPid());

Ответ 12

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

Ответ 13

Запустите второе действие с помощью startActivityForResult и во втором действии верните значение, которое однажды в методе onActivityResult первого действия закрывает основное приложение. Я думаю, что это правильный способ для Android.

Ответ 14

Попробуйте следующее. Это работает для меня.

ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1); 
ComponentName componentInfo = taskInfo.get(0).topActivity;
am.restartPackage(componentInfo.getPackageName());

Ответ 15

На самом деле это спокойно.

То, как я это делаю, - это сохранить флаг в статической переменной, доступной для всех. Затем, когда я выхожу, я устанавливаю этот флаг, и все мои действия проверяют этот флаг onResume. Если флаг установлен, я выдаю System.exit на эту активность.

Таким образом, все действия будут проверять флаг и будут изящно закрываться, если флаг установлен.

Ответ 16

Вы ошибаетесь. Существует один способ убить приложение. В классе с суперклассом Application мы используем какое-то поле, например killApp. Когда мы запускаем заставку (первая активность) в onResume(), мы устанавливаем параметр для false для поля killApp. В каждом действии, которое мы имеем, когда onResume() вызывается в конце, мы вызываем что-то вроде этого:

if(AppClass.killApp())
    finish();

Каждое действие, которое появляется на экране, должно вызывать onResume(). Когда он вызывается, мы должны проверить, истинно ли наше поле killApp. Если это правда, текущие действия вызывают finish(). Чтобы вызвать полное действие, мы используем следующую конструкцию. Например, в действии для кнопки:

AppClass.setkillApplication(true);
   finish();
   return;

Ответ 17

Это то, что я сделал, чтобы закрыть приложение: В моем приложении у меня есть базовый класс активности, я добавил статический флаг под названием "applicationShutDown". Когда мне нужно закрыть приложение, я установил его в true.

В базовом действии onCreate и onResume после вызова супер вызовов я проверяю этот флаг. Если "applicationShutDown" истинно, я вызываю завершение текущего действия.

Это сработало для меня:

protected void onResume() {
    super.onResume();
    if(BaseActivity.shutDownApp)
    {
        finish();
        return;

    }}

Ответ 18

Скажите, что у вас есть стек операций, например A > B > C > D > E. Вы находитесь в действии D, и хотите закрыть приложение. Это то, что вы будете делать -

В операции, с которой вы хотите закрыть (действие D) -

Intent intent = new Intent(D.this,A.class);
intent.putExtra("exit", "exit");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP| Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);

В вашей RootActivity (т.е. ваша базовая активность, здесь Activity A) -

@Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        if (intent.hasExtra("exit")) {
            setIntent(intent);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (getIntent() != null) {
            if (("exit").equalsIgnoreCase(getIntent().getStringExtra(("exit")))) {
                onBackPressed();
            }
        }
    }

onNewIntent используется, потому что если активность активна, он получит первое намерение, которое запустило его. Не новый. Подробнее - Документация

Ответ 19

Запустите второе действие, используя начальную активность для результата:

Intent intent = new Intent(FirstActivity.this, SecondActivity.class);

//This line is important
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);

startActivityForResult(intent, REQUEST_CODE);

Добавьте эту функцию в первую операцию:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(rquestCode == REQUEST_CODE)
        if(resultCode == RESULT_CANCELED)
            finish();
}

И добавьте это ко второму действию:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event)  {
    if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {

        Log.i(TAG, "Back key pressed");
        setResult(RESULT_CANCELED);
        finish();
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

Ответ 20

Не рекомендуется, но вы все равно можете использовать это. Лучше пойти с этим решением, если вам нужно выйти из приложения.

По моему мнению, лучшим решением является завершение всех действий в вашем приложении, как показано ниже.

Шаг 1. Сохраните статическую переменную в mainactivity. Скажем,

public static boolean isQuit = false;

Шаг 2. В событии клика кнопки установите для этой переменной значение true.

mainactivity.isQuit = true;
finish();

Шаг 3. И в каждом действии вашего приложения используйте метод onrestart, как показано ниже.

@Override
protected void onRestart() {
    // TODO Auto-generated method stub
    super.onRestart();
    if(mainactivity.isQuit)
        finish();
}

Ответ 21

Я решил аналогичную проблему: MainActivity начинает BrowserActivity, и мне нужно закрыть приложение, когда пользователь нажимает Back in BrowserActivity - не возвращаться в MainActivity. Итак, в MainActivity:

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "sm500_Rmt.MainActivity";
    private boolean m_IsBrowserStarted = false;

а затем в OnResume:

    @Override
protected void onResume() {
    super.onResume();
    if(m_IsBrowserStarted) {
        Log.w(TAG, "onResume, but it return from browser, just exit!");
        finish();
        return;
    }
    Log.w(TAG, "onResume");

... затем продолжить OnResume. И при запуске BrowserActivity:

    Intent intent = new Intent(this, BrowserActivity.class);
    intent.putExtra(getString(R.string.IPAddr), ip);
    startActivity(intent);
    m_IsBrowserStarted = true;

И похоже, что он работает хорошо!: -)