如何以编程方式退出android应用程序

Vig*_*esh 291 android

我找到了一些以编程方式退出Android应用程序的代码.通过在onDestroy()中调用以下任何一个代码,它会完全退出应用程序吗?

  1. System.runFinalizersOnExit(true)
    (要么)
  2. android.os.Process.killProcess(android.os.Process.myPid());

我不想在单击退出按钮后在后台运行我的应用程序.请问我可以使用这些代码中的任何一个来退出我的应用程序吗?如果可以,我可以使用哪些代码?这是退出Android应用程序的好方法吗?

siv*_*ivi 360

从API 16开始,您可以使用finishAffinity方法,该方法似乎非常接近通过其名称和Javadoc描述关闭所有相关活动:

this.finishAffinity();

完成此活动以及当前任务中具有相同亲缘关系的紧接其下的所有活动.这通常在应用程序可以启动到另一个任务(例如来自它理解的内容类型的ACTION_VIEW)并且用户使用向上导航切换出当前任务并进入其自己的任务时使用.在这种情况下,如果用户已导航到第二个应用程序的任何其他活动,则应将所有这些活动作为任务切换的一部分从原始任务中删除.

请注意,此完成不允许您将结果传递给上一个活动,如果您尝试这样做,则会抛出异常.


从API 21开始,您可以使用非常相似的命令

finishAndRemoveTask();

完成此任务中的所有活动,并将其从最近的任务列表中删除.

  • **肯定这是正确的答案!**使用`System.exit(0);`来完成应用程序不是一个好的解决方案.谢谢您的回答!最后,我找到了一个不错的解决方案. (25认同)
  • 这种解决方案适用于99%的案例.但是,它不会破坏该过程,因此例如Dagger将不会被清除.在极少数情况下,需要杀死进程,`System.exit(0)`是唯一对我有用的解决方案. (5认同)
  • 您知道API 14上是否还有其他解决方案?谢谢 (4认同)
  • 除了@Slav 的回答之外,我还可以补充一点,在使用 Koin 时你也会看到这个问题。即使您使用 finishAndRemoveTask - 重新打开应用程序后,它仍然会将实例保留在内存中。finishAffinity + System.exit(0) 帮助我 (4认同)
  • 警告!this.finishAffinity()关闭app从内存中删除它,所以你不会收到推送消息等等. (3认同)
  • 您可以在关闭应用程序或活动生命周期内单独完成()每个活动. (2认同)
  • `finishAndRemoveTask()` 不适用于 Android N HTC One m9 设备。它刚刚完成了当前的活动。`finishAffinity()` 做到了。 (2认同)

Dev*_*von 148

getActivity().finish();
System.exit(0);
Run Code Online (Sandbox Code Playgroud)

这是退出应用程序的最佳方式.!!!

对我来说最好的解决方案.

  • **我不认为这是一个很好的解决方案.**你不应该使用`System.exit(0);`来完成你的程序.正确的解决方案由@sivi发布(他的答案在上面) (23认同)
  • 这不是解决方案,如果您有一堆活动,它就不起作用 (13认同)

Cri*_*usi 37

finishAffinity();

System.exit(0);

如果您只在finishAffinity();没有System.exit(0);应用程序的情况下使用将退出,但分配的内存仍将由您的手机使用,因此......如果您想要干净且真正退出应用程序,请同时使用它们.

这是最简单的方法,可以在任何地方使用,退出应用程序真实,你可以打开很多活动仍然可以放弃所有没有问题.

单击按钮时的示例

public void exitAppCLICK (View view) {

    finishAffinity();
    System.exit(0);

}
Run Code Online (Sandbox Code Playgroud)

或者如果你想要一些不错的东西,例如带有3个按钮的警告对话框是NO和CANCEL

// alertdialog for exit the app
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);

// set the title of the Alert Dialog
alertDialogBuilder.setTitle("your title");

// set dialog message
alertDialogBuilder
        .setMessage("your message")
        .setCancelable(false)
        .setPositiveButton("YES"),
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog,
                                        int id) {
                        // what to do if YES is tapped
                        finishAffinity();
                        System.exit(0);
                    }
                })

        .setNeutralButton("CANCEL"),
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog,
                                        int id) {
                        // code to do on CANCEL tapped
                        dialog.cancel();
                    }
                })

        .setNegativeButton("NO"),
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog,
                                        int id) {
                        // code to do on NO tapped
                        dialog.cancel();
                    }
                });

AlertDialog alertDialog = alertDialogBuilder.create();

alertDialog.show();
Run Code Online (Sandbox Code Playgroud)

  • 这是正确的答案,我一直在寻找.谢谢 (2认同)

Nan*_*nne 29

如果你确实需要杀死应用程序,请认真思考:为什么不让操作系统弄清楚何时何地释放资源?

否则,如果你真的很确定,请使用

finish();
Run Code Online (Sandbox Code Playgroud)

作为对@dave appleton评论的反应:第一件事是读了大问题/答案组合@gabriel发布:退出一个应用程序不赞成

现在假设我们有这个问题,这里的问题仍然有一个答案,就是如果你正在做任何退出的事情你需要的代码是finish().显然你可以有不止一个活动等等,但这不是重点.让我们运行一些用例

  1. 你想让用户因内存使用和"不在后台运行"而退出所有内容吗?Doubtfull.让用户在后台停止某些活动,但让操作系统杀死任何不需要的资源.
  2. 您希望用户不要转到您应用的上一个活动吗?好吧,要么配置它没有,要么你需要一个额外的选项.如果back = previous-activity的大部分时间都有效,那么如果用户想要做其他事情,用户是否只会按回家?
  3. 如果您需要某种重置,您可以查看您的应用程序是否/如何/等退出,如果您的活动再次获得焦点,您可以对此采取措施,显示一个新屏幕,而不是重新启动您所在的位置.

因此,最后,当然,finish()并不会扼杀,但它仍然是我认为你需要的工具.如果有"杀死所有活动"的用例,我还没有找到它.

  • 大多数Android应用程序都有多个活动. (42认同)
  • 调用`finish()`不会杀死应用程序.`finish()`一直被使用:`当你的活动完成后调用它并且应该关闭它.它与点击"后退"按钮的效果相同. (29认同)
  • @Nanne - 锁定屏幕是您想要停止所有活动的示例.假设您登录银行应用程序.在没有来自用户的交互的一段时间之后,锁定屏幕启动.如果有人从锁定屏幕点击后退按钮,您将要停止所有活动! (4认同)

sun*_*hun 19

我认为在某些情况下应用程序应该是kill.例如,有一个应用程序只能在登录后使用.登录活动有两个按钮,"登录"和"取消".当您单击"取消"按钮时,它肯定意味着"终止应用程序".没有人希望应用程序在后台运行.所以我同意某些情况需要关闭应用程序.

  • 我完全同意这个用例.还要考虑我必须在某个位置可用的安全应用程序,如果用户不在该位置,最好关闭它.我该怎么办? (2认同)

san*_*san 18

Android中没有应用程序退出,SampleActivity.this.finish(); 将完成当前的活动.

当您从一个活动切换到另一个活动时,请完成前一个活动

Intent homeintent = new Intent(SampleActivity.this,SecondActivity.class);
startActivity(homeintent);
SampleActivity.this.finish();
Run Code Online (Sandbox Code Playgroud)


viv*_*vek 15

创建一个ExitActivity并在清单中声明它.并要求ExitActivity.exit(context)退出应用程序.

public class ExitActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        finish();
    }

    public static void exit(Context context) {
        Intent intent = new Intent(context, ExitActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
        context.startActivity(intent);
    }

}
Run Code Online (Sandbox Code Playgroud)

  • 记得在你的清单中声明这个类。聪明的黑客+1。 (2认同)

Jer*_*ong 9

类似于@MobileMateo,但在Kotlin 中

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
    this.finishAffinity()
} else{
    this.finish()
    System.exit(0)
}
Run Code Online (Sandbox Code Playgroud)


Vin*_*ins 8

您可以使用finishAndRemoveTask ()API 21

public void finishAndRemoveTask()

完成此任务中的所有活动,并将其从最近的任务列表中删除.


小智 8

这取决于您想要关闭应用的速度.

关闭应用程序的一种安全方法是finishAffinity();

在所有流程完成处理后,它会关闭您的app.这可能需要一些时间.如果以这种方式关闭应用程序,并在短时间后重新启动它,则新应用程序可能在同一进程中运行.使用旧应用程序的所有未完成的进程和单例对象.

如果你想确定,你的应用程序是完全关闭使用System.exit(0);

这将立即关闭您的应用程序.但是,您可能会损坏应用程序已打开的文件或共享首选项上的编辑未完成.所以要小心使用.

如果将watchdog与长时间运行的任务结合使用,则可以看到不同方法的影响.

new ANRWatchDog(2000).setANRListener(new ANRWatchDog.ANRListener() {
    public void onAppNotResponding(ANRError error) {
        MainActivity.this.finishAffinity();
        System.exit(0);
    }
}).start();
for(int i = 0; i < 10; ++i){
    --i;
}
Run Code Online (Sandbox Code Playgroud)

这会在2秒后杀死您的应用,而不会显示ANR对话框或类似内容.如果删除System.exit(0),运行此代码并在关闭后重新启动应用程序,您将遇到一些奇怪的行为,因为无限循环仍在运行.


Far*_*aev 8

finish()如果你在Activity,或者getActivity().finish()如果你在,你最好使用Fragment.

如果您想完全退出应用程序,请使用:

getActivity().finish();
System.exit(0);
Run Code Online (Sandbox Code Playgroud)


twe*_*11k 8

首先,这种方法需要最小Api 16.

我将此解决方案分为3个部分,以更广泛地解决这个问题.

1.如果要在活动中退出应用程序,请使用以下代码段:

if(Build.VERSION.SDK_INT>=16 && Build.VERSION.SDK_INT<21){
            finishAffinity();
        } else if(Build.VERSION.SDK_INT>=21){
            finishAndRemoveTask();
        }
Run Code Online (Sandbox Code Playgroud)

2.如果要退出具有Activity访问权限的非Activity类中的应用程序,请使用以下代码段:

    if(Build.VERSION.SDK_INT>=16 && Build.VERSION.SDK_INT<21){
                getActivity().finishAffinity();
            } else if(Build.VERSION.SDK_INT>=21){
                getActivity().finishAndRemoveTask();
            }
Run Code Online (Sandbox Code Playgroud)

3.如果要退出非Activity类中的应用程序而无法访问Service等活动,我建议您使用BroadcastReceiver.您可以将此方法添加到项目中的所有活动中.

创建LocalBroadcastManager和BroadcastReceiver实例变量.如果需要,可以替换getPackageName()+".closeapp".

LocalBroadcastManager mLocalBroadcastManager;
BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        if(intent.getAction().equals(getPackageName()+".closeapp")){
            if(Build.VERSION.SDK_INT>=16 && Build.VERSION.SDK_INT<21){
                finishAffinity();
            } else if(Build.VERSION.SDK_INT>=21){
                finishAndRemoveTask();
            }
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

将这些添加到Activity的onCreate()方法中.

    mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);
    IntentFilter mIntentFilter = new IntentFilter();
    mIntentFilter.addAction(getPackageName()+".closeapp");
    mLocalBroadcastManager.registerReceiver(mBroadcastReceiver, mIntentFilter);
Run Code Online (Sandbox Code Playgroud)

另外,不要忘记在Activity的onDestroy()方法中调用unregister接收器

    mLocalBroadcastManager.unregisterReceiver(mBroadcastReceiver);
Run Code Online (Sandbox Code Playgroud)

对于退出应用程序,您必须使用我在PlayService类中使用的LocalBroadcastManager发送广播,该类扩展了Service.

  LocalBroadcastManager localBroadcastManager = LocalBroadcastManager
                                .getInstance(PlayService.this);
                        localBroadcastManager.sendBroadcast(new Intent(
                                getPackageName() + ".closeapp"));
Run Code Online (Sandbox Code Playgroud)


小智 8

朋友只需添加此函数即可以编程方式退出您的应用程序#java

public void onBackPressed() 
{

    finishAffinity();
    System.exit(0);
}
Run Code Online (Sandbox Code Playgroud)


小智 7

我们想要健壮且简单的代码。此解决方案适用于旧设备和新设备。

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        getActivity().finishAffinity();
    } else{
        getActivity().finish();
        System.exit( 0 );
    }
Run Code Online (Sandbox Code Playgroud)


Has*_*mil 6

从应用程序退出的简单方法

Intent homeIntent = new Intent(Intent.ACTION_MAIN);
homeIntent.addCategory(Intent.CATEGORY_HOME);
homeIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(homeIntent);
Run Code Online (Sandbox Code Playgroud)


Mic*_*cer 6

如果您使用 Kotlin,退出应用程序的正确方法和替代方法System.exit()是内置方法

exitProcess(0)
Run Code Online (Sandbox Code Playgroud)

请参阅文档

数字0作为参数意味着退出是有意的,没有发生错误。


Sag*_*ius 6

如果您想关闭您的应用程序:

对于 API >= 21,使用:

finishAndRemoveTask();
Run Code Online (Sandbox Code Playgroud)

对于 API < 21 使用:

finishAffinity();
Run Code Online (Sandbox Code Playgroud)


Rag*_*dan 5

退出申请是否令人不悦?. 通过这个链接。它回答了你的问题。系统执行终止应用程序的工作。

假设您有两个活动 A 和 B。您从 A 导航到 B。当您单击后退按钮时,您的活动 B 将从后台堆栈中弹出并销毁。返回堆栈活动 A 中的先前活动获得关注。

您应该让系统决定何时终止应用程序。

公共无效 finish()

当您的活动完成并且应该关闭时调用它。

假设你有很多活动。您可以使用操作栏。单击主页图标导航到应用程序的 MainActivity。在 MainActivity 单击后退按钮退出应用程序。


Jab*_*ari 5

我不确定这是不是不赞成,但这就是我这样做的方式......

第1步 -我通常有一个包含我想要全局访问的方法和变量的类.在这个例子中,我将其称为"App"类.在应用程序具有的每个活动的类中创建一个静态Activity变量.然后创建一个名为"close"的静态方法,如果它们不为null,将finish()在每个Activity变量上运行该方法.如果您有主/父活动,请将其关闭:

public class App
{
    ////////////////////////////////////////////////////////////////
    // INSTANTIATED ACTIVITY VARIABLES
    ////////////////////////////////////////////////////////////////

        public static Activity activity1;
        public static Activity activity2;
        public static Activity activity3;

    ////////////////////////////////////////////////////////////////
    // CLOSE APP METHOD
    ////////////////////////////////////////////////////////////////

        public static void close()
        {
            if (App.activity3 != null) {App.activity3.finish();}
            if (App.activity2 != null) {App.activity2.finish();}
            if (App.activity1 != null) {App.activity1.finish();}
        }
}
Run Code Online (Sandbox Code Playgroud)

第2步 -在每个活动中,覆盖onStart()onDestroy()方法.在onStart(),将App类中的静态变量设置为" this".在onDestroy(),设置它等于null.例如,在"Activity1"类中:

@Override
public void onStart()
{
    // RUN SUPER | REGISTER ACTIVITY AS INSTANTIATED IN APP CLASS

        super.onStart();
        App.activity1 = this;
}

@Override
public void onDestroy()
{
    // RUN SUPER | REGISTER ACTIVITY AS NULL IN APP CLASS

        super.onDestroy();
        App.activity1 = null;
}
Run Code Online (Sandbox Code Playgroud)

第3步 -当您想关闭应用时,只需App.close()从任何地方拨打电话即可.所有实例化的活动都将关闭!由于您只是关闭活动而不是杀死应用程序本身(如您的示例中所示),因此Android可以从那里接管并进行任何必要的清理.

同样,我不知道这是否会因任何原因而不受欢迎.如果是这样,我很乐意阅读有关它为何以及如何改进的评论!

  • 通过保持对您的活动的引用,您实际上是在泄漏内存!请参阅[this](http://android-developers.blogspot.de/2009/01/avoiding-memory-leaks.html)进行深入讨论. (4认同)

Cip*_*ian 5

我认为你在寻找的是这个

activity.moveTaskToBack(Boolean nonRoot);
Run Code Online (Sandbox Code Playgroud)


med*_*igo 5

public void quit() {
        int pid = android.os.Process.myPid();
        android.os.Process.killProcess(pid);
        System.exit(0);
    }
Run Code Online (Sandbox Code Playgroud)

  • 如果有多个活动,[System.exit()不会终止Android应用程序](http://stackoverflow.com/questions/2033914/quitting-an-application-is-that-frowned-upon/2043734#2043734 ) (2认同)

Ami*_*deh 5

要退出您的应用程序,您可以使用以下命令:

getActivity().finish();
Process.killProcess(Process.myPid());
System.exit(1);
Run Code Online (Sandbox Code Playgroud)

另外,要停止服务也可以调用以下方法:

private void stopServices() {        
    final ActivityManager activityManager = SystemServices.getActivityManager(context);
    final List<ActivityManager.RunningServiceInfo> runningServices = activityManager.getRunningServices(Integer.MAX_VALUE);
    final int pid = Process.myPid();
    for (ActivityManager.RunningServiceInfo serviceInfo : runningServices) {
        if (serviceInfo.pid == pid && !SenderService.class.getName().equals(serviceInfo.service.getClassName())) {
            try {
                final Intent intent = new Intent();
                intent.setComponent(serviceInfo.service);
                context.stopService(intent);
            } catch (SecurityException e) { 
                 // handle exception
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)