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

Close application and launch home screen on Android

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


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

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

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

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

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


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

  • 使用此Intent启动活动:

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

  • 步骤说明:

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

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


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


    Android有一个机制来根据其文档安全地关闭应用程序。在退出的最后一个Activity(通常是应用程序启动时首次出现的主Activity)中,只需在onDestroy()方法中放置几行。对System.runFinalizersOnExit(true)的调用可确保在应用程序退出时完成所有对象并进行垃圾回收。例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    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键事件保留给自己,以便开发人员无法阻止用户离开其应用程序。


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

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

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


    我用这个方法关闭活动!

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    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;
            }
        }
    }

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

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


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


    我用这个:

    1)父活动使用方法"startActivityForResult"调用辅助活动

    2)在关闭时的辅助活动中:

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

    3)并在父活动中覆盖方法"onActivityResult":

    1
    2
    3
    4
    5
    6
    7
    8
    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();
        }
    }

    这对我来说很好。


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

    1
    this.finish();

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

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


    请尝试以下方法。这个对我有用。

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

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


    假设你有活动堆栈,如A> B> C> D> E.您在活动D,并且想要关闭您的应用。这就是你要做的 -

    在您要关闭的活动中(活动D) -

    1
    2
    3
    4
    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) -

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    @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是因为如果活动处于活动状态,它将获得启动它的第一个意图。不是新的。
    有关更多详细信息 - 文档


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


    它实际上很安静。

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

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


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

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

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

    1
    2
    3
    AppClass.setkillApplication(true);
       finish();
       return;


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

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

    这对我有用:

    1
    2
    3
    4
    5
    6
    7
    8
    protected void onResume() {
        super.onResume();
        if(BaseActivity.shutDownApp)
        {
            finish();
            return;

        }}

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

    1
    2
    3
    4
    5
    6
    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:

    1
    2
    3
    4
    5
    6
    7
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(rquestCode == REQUEST_CODE)
            if(resultCode == RESULT_CANCELED)
                finish();
    }

    并将其添加到第二个Activity:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @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);
    }


    我解决了类似的问题:MainActivity启动BrowserActivity,当用户在BrowserActivity中按Back时,我需要关闭应用程序 - 而不是在MainActivity中返回。那么,在MainActivity中:

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

    然后,在OnResume中:

    1
    2
    3
    4
    5
    6
    7
    8
    9
        @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时:

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

    它看起来很好用! :-)


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

    据我所知,最好的解决方案是完成你的应用程序中的每个活动,如下所示。

    步骤1.在mainactivity中维护一个静态变量。说,

    1
    public static boolean isQuit = false;

    步骤2.在按钮的单击事件上,将此变量设置为true。

    1
    2
    mainactivity.isQuit = true;
    finish();

    步骤3.在应用程序的每个活动中,使用如下的onrestart方法。

    1
    2
    3
    4
    5
    6
    7
    @Override
    protected void onRestart() {
        // TODO Auto-generated method stub
        super.onRestart();
        if(mainactivity.isQuit)
            finish();
    }