76

我有两个不同的活动。第一个启动第二个。在第二个活动中,我调用System.exit(0)以强制关闭应用程序,但第一个活动会自动显示,而不是应用程序返回主屏幕。我怎样才能避免这种情况,并让应用程序返回主屏幕?

4

21 回答 21

87

简短的回答:调用moveTaskToBack(true)你的Activity而不是System.exit(). 这将隐藏您的应用程序,直到用户想要再次使用它。

更长的答案从另一个问题开始:你为什么要杀死你的应用程序?

Android 操作系统处理内存管理和进程等,所以我的建议是让 Android 为您担心这些。如果用户想离开您的应用程序,他们可以按 Home 按钮,您的应用程序将有效地消失。如果手机稍后需要更多内存,操作系统将终止您的应用程序。

只要您适当地响应生命周期事件,您和用户都不需要关心您的应用程序是否仍在运行。

因此,如果您想隐藏您的应用程序调用moveTaskToBack()并让 Android 决定何时终止它。

于 2010-01-11T14:59:27.427 回答
53

下面给出了实现这一点的最简单方法(不影响 Android 的本机内存管理。不涉及进程终止)。

  1. 使用这个 Intent 启动一个活动:

    Intent intent = new Intent(this, FinActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(intent);
    finish();
    
  2. 在目标活动FinActivity.class中,调用finish() onCreate

步骤说明:

  1. 您创建一个删除所有其他活动(FLAG_ACTIVITY_CLEAR_TOP)并删除当前活动的意图。

  2. 活动会自我毁灭。另一种方法是您可以在 finActivity 中制作启动画面。这是可选的。

于 2011-01-19T16:08:13.787 回答
45

你真的应该考虑不退出应用程序。这不是 Android 应用程序通常的工作方式。

于 2010-01-11T16:49:56.457 回答
20

Android 有一种机制可以根据其文档安全地关闭应用程序。在退出的最后一个 Activity(通常是应用程序启动时首先出现的主 Activity)中,只需在 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键事件保留给自己,以便开发人员无法阻止用户离开他们的应用程序。

于 2011-02-18T19:44:21.593 回答
9

您还可以在第一个活动的标签中指定noHistory = "true" 或在您开始第二个活动后立即完成第一个活动(如大卫所说)。

AFAIK,“强制关闭”会终止托管您的应用程序运行所在的 JVM 的进程,并且 System.exit() 会终止运行您的应用程序实例的 JVM。两者都是突然终止的形式,不建议用于正常的应用程序流程。

正如捕获异常以覆盖程序可能执行的逻辑流一样,也不可取。

于 2010-01-11T14:32:25.873 回答
9

我用这个方法来关闭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;
        }
    }
}
于 2011-04-15T04:06:32.387 回答
8

当您启动第二个活动时,finish()第一个活动立即:

startActivity(new Intent(...));
finish();
于 2010-01-11T13:55:09.007 回答
6

android.os.Process.killProcess(android.os.Process.myPid());工作正常,但建议让Android平台担心内存管理:-)

于 2010-06-15T03:46:41.487 回答
4

你不能做 System.exit(),它不安全。

你可以这样做: Process.killProcess(Process.myPid());

于 2010-01-11T14:58:44.107 回答
4

我用这个:

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();
    }
}

这对我来说很好。

于 2012-05-05T11:32:38.460 回答
4

使用finish方法。这是更简单、更容易的方法。

this.finish();
于 2010-11-17T06:57:39.197 回答
2

你错了。有一种方法可以杀死应用程序。在具有超类 Application 的类中,我们使用一些字段,例如killApp. 当我们在 中启动启动画面(第一个活动)时onResume(),我们为 field 设置了一个参数为 false killApp。在最后调用的每个活动中onResume(),我们调用类似的东西:

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

每个进入屏幕的活动都必须调用onResume()。当它被调用时,我们必须检查我们的字段killApp是否为真。如果是真的,当前活动调用finish(). 为了调用完整的动作,我们使用下一个构造。例如,在按钮的操作中:

AppClass.setkillApplication(true);
   finish();
   return;
于 2012-02-22T14:06:10.623 回答
2

试试下面的。这个对我有用。

ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1); 
ComponentName componentInfo = taskInfo.get(0).topActivity;
am.restartPackage(componentInfo.getPackageName());
于 2011-08-11T08:31:36.620 回答
2

使用 startActivityForResult 启动第二个活动,并在第二个活动中返回一个值,一旦在第一个活动的 onActivityResult 方法中关闭主应用程序。我认为这是 Android 的正确做法。

于 2011-04-04T07:53:30.000 回答
2

假设您有 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(即您的基本活动,此处为活动 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 是因为如果活动处于活动状态,它将获得启动它的第一个意图。不是新的。有关更多详细信息 -文档

于 2014-10-08T13:42:32.943 回答
2

请记住,在处理使用持久套接字连接的应用程序时,该finish()方法不会释放连接。在正常情况下,finish()是最好的选择,但如果你绝对需要退出一个应用程序并释放它正在使用的所有资源,那么使用killProcess. 我使用它没有任何问题。

于 2011-01-13T14:39:23.930 回答
1

这是我关闭应用程序所做的:在我的应用程序中,我有一个基本活动类,我添加了一个名为“applicationShutDown”的静态标志。当我需要关闭应用程序时,我将其设置为 true。

在调用超级调用后的基本活动 onCreate 和 onResume 中,我测试了这个标志。如果“applicationShutDown”为真,我会在当前 Activity 上调用完成。

这对我有用:

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

    }}
于 2014-02-02T16:16:00.573 回答
1

它实际上很容易安静。

我这样做的方法是在所有人都可以使用的静态变量中保存一个标志。然后,当我退出时,我设置了这个标志,我的所有活动都会检查这个标志onResume。如果设置了标志,那么我会System.exit在该活动上发出。

这样,所有活动都将检查标志,如果设置了标志,则会正常关闭。

于 2011-09-07T16:53:14.683 回答
0

不推荐,但您仍然可以使用它。如果您需要退出应用程序,最好使用此解决方案。

根据我的说法,最好的解决方案是完成您应用中的所有活动,如下所示。

步骤 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();
}
于 2012-06-21T12:03:28.967 回答
0

使用 start 活动运行第二个活动以获得结果:

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

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

startActivityForResult(intent, REQUEST_CODE);

将此函数添加到第一个 Activity:

@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);
}
于 2011-09-26T10:03:03.427 回答
0

我解决了一个类似的问题:MainActivity 启动 BrowserActivity,当用户在 BrowserActivity 中按下 Back 时,我需要关闭应用程序 - 而不是在 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's 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;

而且看起来效果很好!:-)

于 2017-06-22T17:10:14.233 回答