在Android上关闭应用程序并启动主屏幕

时间:2010-01-11 13:52:00

标签: android android-activity

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

21 个答案:

答案 0 :(得分:88)

简答:致电moveTaskToBack(true) on your Activity而非System.exit()。这将隐藏您的应用程序,直到用户想要再次使用它。

更长的答案从另一个问题开始:你为什么要杀死你的申请?

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

只要您是responding to lifecycle events appropriately,您和用户都不需要关心您的应用程序是否仍在运行。

因此,如果你想隐藏你的应用程序调用{​​{1}},让Android决定何时杀死它。

答案 1 :(得分:53)

实现此目的的最简单方法如下(不影响Android的本机内存管理。不涉及进程终止)。

  1. 使用此Intent启动活动:

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

  3. 步骤说明:

    1. 您创建的目标会删除所有其他活动(FLAG_ACTIVITY_CLEAR_TOP)并删除当前活动。

    2. 活动摧毁了自己。另一种方法是,您可以在finActivity中制作闪屏。这是可选的。

答案 2 :(得分:45)

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

答案 3 :(得分: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 键事件保留给自己,以便开发人员无法阻止用户离开其应用程序。

答案 4 :(得分:9)

您还可以在第一个活动的标签中指定noHistory =“true”,或者在启动第二个活动后立即完成第一个活动(如David所说)。

AFAIK,“强制关闭”会终止承载运行应用程序的JVM的进程 System.exit()终止运行应用程序实例的JVM。两者都是突然终止的形式,不适用于正常的应用程序流程。

正如捕获异常以涵盖程序可能采用的逻辑流程一样,这是不可取的。

答案 5 :(得分:9)

我使用此方法关闭活动!

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

答案 6 :(得分:8)

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

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

答案 7 :(得分:6)

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

答案 8 :(得分:4)

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

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

答案 9 :(得分:4)

使用finish方法。这是一种更简单,更容易的方法。

this.finish();

答案 10 :(得分: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();
    }
}

这对我来说很好。

答案 11 :(得分:2)

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

答案 12 :(得分: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是因为如果活动处于活动状态,它将获得启动它的第一个意图。不是新的。 有关详情 - Documentation

答案 13 :(得分: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());

答案 14 :(得分:2)

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

答案 15 :(得分:1)

实际上很安静。

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

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

答案 16 :(得分:1)

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

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

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

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

答案 17 :(得分:1)

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

在调用超级调用后的基础活动onCreate和onResume中,我测试了这个标志。 如果“applicationShutDown”为true,则在当前Activity上调用finish。

这对我有用:

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

    }}

答案 18 :(得分:0)

使用结果的开始活动运行第二个活动:

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

答案 19 :(得分: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();
}

答案 20 :(得分: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;

它看起来效果很好! : - )