ChatGPT解决这个技术问题 Extra ChatGPT

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

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

System.runFinalizersOnExit(true) (OR) android.os.Process.killProcess(android.os.Process.myPid());

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

这里已经有很多帖子了。 stackoverflow.com/search?q=how+to+exit+an+android+app
使用'System.exit(0);'当您真的想退出应用程序时。在向用户显示消息后,我在一个不可恢复的错误中完成了该操作。如果需要,您甚至可以使用 AlarmManager 自动重新启动应用程序。请参阅:blog.janjonas.net/2010-12-20/…
第二个选项使它看起来像一个崩溃

C
Community

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

this.finishAffinity();

在当前任务中完成此活动以及紧接其下的所有具有相同亲和力的活动。这通常用于当应用程序可以启动到另一个任务(例如从它理解的内容类型的 ACTION_VIEW)并且用户已经使用向上导航从当前任务切换到自己的任务时使用。在这种情况下,如果用户向下导航到第二个应用程序的任何其他活动,则所有这些活动都应作为任务切换的一部分从原始任务中删除。请注意,此完成不允许您将结果传递给先前的活动,如果您尝试这样做,则会引发异常。

由于 API 21,您可以使用非常相似的命令

finishAndRemoveTask();

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


这绝对是正确答案! 使用 System.exit(0); 完成应用程序并不是一个好的解决方案。谢谢您的回答!最后我找到了一个不错的解决方案。
你知道 API 14 上是否有其他解决方案吗?谢谢
警告! this.finishAffinity() 关闭应用程序,将其从内存中删除,因此您不会收到推送消息等。
该解决方案适用于 99% 的情况。但是,它不会破坏进程,例如 Dagger 不会被清除。在需要终止进程的极少数情况下,System.exit(0) 是唯一对我有用的解决方案。
除了@Slav 回答,我还可以补充一点,在使用 Koin 时,您也会看到这个问题。即使您使用 finishAndRemoveTask - 在重新打开应用程序后,它仍会将实例保留在内存中。 finishAffinity + System.exit(0) 帮帮我
A
Ashton
getActivity().finish();
System.exit(0);

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

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


是的,效果很好!必须从 MainActivity 调用它才能让它工作!
完美的解决方案。无需终止进程,因为 Android 最了解内存管理。但是,这为完成活动以及退出应用程序以方便用户提供了解决方案。
真正的完美解决方案。修复了很多问题。谢谢。
我认为这不是一个好的解决方案。不应该使用 System.exit(0); 完成您的程序。 @sivi 发布了正确的解决方案(他的答案在上面)
这不是解决方案,如果您有一堆活动,它就不起作用
P
Paul Chu

finishAffinity();

System.exit(0);

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

这是最简单的方法,在任何地方都可以使用,真正退出应用程序,您可以打开很多活动,但仍然可以毫无问题地退出所有活动。

单击按钮的示例

public void exitAppCLICK (View view) {

    finishAffinity();
    System.exit(0);

}

或者,如果您想要一些不错的东西,例如带有 3 个按钮 YES 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();

这是正确的答案,我一直在寻找。谢谢
如果我在我的应用程序中使用 FCM 或后台任务,我会没有问题?
这就是我从内存中擦除应用程序所需要的
请不要使用System.exit(0);你不应该释放那个内存,如果需要系统会为你做。这是预期的行为。
C
Community

请认真考虑是否确实需要终止应用程序:为什么不让操作系统弄清楚何时何地释放资源?

否则,如果您非常确定,请使用

finish();

作为对@dave appleton 评论的回应:首先阅读@gabriel 发布的大问题/答案组合:Is quitting an application frowned upon?

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

你想让用户因为内存使用而退出一切并且“没有在后台运行?Doubtfull。让用户在后台停止某些活动,但让操作系统杀死任何不需要的资源。你希望用户不要去您的应用程序的先前活动?好吧,要么将其配置为不使用,要么您需要一个额外的选项。如果大多数情况下 back=previous-activity 有效,那么用户是否会根据需要按主页做其他事情吗?如果您需要某种重置,您可以了解您的应用程序是否/如何/等等,如果您的活动再次获得焦点,您可以对其采取行动,显示新屏幕而不是重新启动您所在的位置是。

所以最后,当然,finish() 不会杀死一切,但我认为它仍然是您需要的工具。如果有“杀死所有活动”的用例,我还没有找到。


调用 finish() 不会终止应用程序。 finish() 一直使用:Call this when your activity is done and should be closed. 与点击“返回”按钮的效果相同。
完成将终止活动。这与杀死应用程序有何不同?
“完成”或“杀死”Activity(不是 Application)没有任何问题。例如,您可能会启动一个新活动来向用户显示一些信息。超时或按“确定”后,您可能会调用 finish() 以返回调用活动。
大多数 Android 应用程序都有不止一项活动。
@Nanne - 锁定屏幕是您想要停止所有活动的示例。假设您登录到银行应用程序。在一段时间没有用户交互后,锁定屏幕启动。如果有人从锁定屏幕点击后退按钮,您会想要停止所有活动!
v
vivek

创建一个 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);
    }

}

这是投票最多的答案,但它是一个黑客。在大多数(如果不是全部)设备上,在 onCreate 中调用完成会出现故障。
嗯,它是一个黑客,但不是一个小故障。您将调用的第一个 exit(),它位于所有活动的顶部,具有明确的顶部和任务,然后自行完成。在这里你退出。
请记住在清单中声明此类。虽然为聪明的黑客+1。
最佳答案在这里,其他没有尝试上述解决方案,没有这个解决方案没有任何工作
最佳答案。我实际上需要重新启动我的应用程序,因为我添加了 startActivity(new Intent(this, SplashAcitivity.class));在调用完成()之前;在这个 ExitActivity 中的 onCreate 中,这非常棒。
s
sunghun

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


我完全同意这个用例。还要考虑我的安全应用程序,它必须在某个位置可用,并且如果用户不在该位置,最好关闭它。我该怎么办?
T
Thomas Dignan

android中没有应用退出,SampleActivity.this.finish();将完成当前活动。

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

Intent homeintent = new Intent(SampleActivity.this,SecondActivity.class);
startActivity(homeintent);
SampleActivity.this.finish();

R
Rutvik Bhatt

首先,这种方法需要最低 Api 16。

我将把这个解决方案分成 3 个部分来更广泛地解决这个问题。

1. 如果您想在 Activity 中退出应用程序,请使用以下代码片段:

if(Build.VERSION.SDK_INT>=16 && Build.VERSION.SDK_INT<21){
    finishAffinity();
} else if(Build.VERSION.SDK_INT>=21){
    finishAndRemoveTask();
}

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

3. 如果你想在非Activity类中退出应用,又无法访问Service等Activity,我推荐你使用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();
            }
        }
    }
};

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

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

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

mLocalBroadcastManager.unregisterReceiver(mBroadcastReceiver);

对于退出应用程序,您必须使用我在扩展服务的 PlayService 类中使用的 LocalBroadcastManager 发送广播。

LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(PlayService.this);
localBroadcastManager.sendBroadcast(new Intent(getPackageName() + ".closeapp"));

V
Vins

您可以使用 API 21 中的 finishAndRemoveTask ()

public void finishAndRemoveTask () 完成此任务中的所有活动并将其从最近的任务列表中删除。


u
user3424426

这取决于您想要关闭应用程序的速度。

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

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

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

这将立即关闭您的应用程序。但是,您可能会损坏您的应用程序已打开的文件,或者对共享首选项的编辑未完成。所以请谨慎使用。

如果您将看门狗与长时间运行的任务结合使用,您可以看到不同方法的影响。

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

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


您说它将关闭应用程序而不显示 ANR 对话框。这是否意味着 Google 商店不会收到有关 ANR 事件的信息?
@EvgenyGerbut 我从未在已发布的应用程序中运行此代码片段,它仅用于科学。但我很确定,如果您发现自己的 ANR 并在没有错误的情况下关闭应用程序,Google 将不会被告知 ANR。
ᴛʜᴇᴘᴀᴛᴇʟ

如果您在 Activity,最好使用 finish(),如果您在 Fragment,最好使用 getActivity().finish()

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

getActivity().finish();
System.exit(0);

H
Hassnain Jamil

退出应用程序的简单方法

Intent homeIntent = new Intent(Intent.ACTION_MAIN);
homeIntent.addCategory(Intent.CATEGORY_HOME);
homeIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(homeIntent);

这只是带来主屏幕还是实际上杀死了应用程序?
J
Jerry Chong

类似于@MobileMateo,但在 Kotlin 中

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

M
MobileMateo

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

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

C
Ciprian

我想你要找的是这个

activity.moveTaskToBack(Boolean nonRoot);

S
Sagittarius

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

对于 API >= 21,请使用:

finishAndRemoveTask();

对于 API < 21,请使用:

finishAffinity();

m
meduvigo
public void quit() {
        int pid = android.os.Process.myPid();
        android.os.Process.killProcess(pid);
        System.exit(0);
    }

M
Micer

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

exitProcess(0)

请参阅 documentation

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


2
2 revs, 2 users 82%

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

public void onBackPressed() 
{

    finishAffinity();
    System.exit(0);
}

使用它并发表评论
Kotlin 版本:finishAffinity();退出进程(0);谢谢多兰,这就是我下面不需要的东西
J
Jabari

我不确定这是否令人不悦,但这就是我的做法......

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

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

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

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

再说一次,我不知道这是否会因任何原因而被反对。如果是这样,我很乐意阅读有关它为什么以及如何改进的评论!


通过保留对您的活动的引用,您实际上是在泄漏内存!有关深入讨论,请参阅 this
@Managarm 该帖子背后的前提是,即使在进程(在本例中为活动)被销毁后,静态变量仍将保留。但是,如果进行了适当的房屋清洁,这不是问题……因此我取消了活动的 onDestroy() 方法中的引用的原因。
@Jabari 啊,我错过了 onDestroy 部分。在这种情况下,它不应该是一个问题,尽管它不是最佳实践。
@Managarm 我承认它依赖于程序员进行尽职调查,我完全理解如何轻松查看它!也就是说,我们都应该在编码时将这些事情放在脑海中。我们还应该在部署之前大量测试内存问题!
工作没有任何问题。对于 api>=16 使用 finishAffinity() 否则使用此方法。
C
Community

Is quitting an application frowned upon?。通过这个链接。它回答了你的问题。系统执行终止应用程序的工作。

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

您应该将其留给系统来决定何时终止应用程序。

公共无效finish()

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

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


a
amrezzd

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

getActivity().finish();
Process.killProcess(Process.myPid());
System.exit(1);

还要停止服务也调用以下方法:

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

A
Aalok Sharma

这可能已经很晚了,而且根据您不应该自己处理生命周期过程的指南(因为操作系统会为您执行此操作)。建议您在所有活动中注册广播接收器,并在其 onReceive() 中使用“finish()”。每当您想退出时,您可以简单地传递一个指示所有活动必须关闭的意图......尽管请确保您在 onDestroy() 方法中“取消注册”接收器。


P
Pir Fahim Shah

单击按钮时退出应用程序的正确且准确的解决方案是使用以下代码:

//On Button Back按下事件

public void onBackPressed()
{ 
   moveTaskToBack(true);
   finish();
}

这完全是当前的 Android 组件(例如活动),而不是整个应用程序。
这只会在后台发送应用程序
E
Egor

这不是一个好的决定,因为它违反了 Android 的应用程序处理原则。除非绝对不可避免,否则 Android 不会杀死任何进程。这有助于应用程序更快地启动,因为它们始终保存在内存中。所以你需要一个非常特殊的理由来杀死你的应用程序的进程。


退出应用程序需要真正杀死该应用程序。所以应该有一种方法可以确保退出后应用程序被杀死
D
D.Snap

这会杀死任何东西;)

int p = android.os.Process.myPid();
android.os.Process.killProcess(p);

A
Ahmer Afzal

尝试这个

int pid = android.os.Process.myPid();
android.os.Process.killProcess(pid);

佚名

我发现从活动中退出应用程序的最简单方法如下:

public static void quitApplication (Activity currentActivity) {
    Intent intent = new Intent (currentActivity, QuitApplicationActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);

    currentActivity.startActivity (intent);
    currentActivity.finish ();
}

QuitApplicationActivity 是:

public class QuitApplicationActivity extends AppCompatActivity {

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

        finish ();
    }
}

S
Saeed Vrz

@Sivi 的回答关闭了应用程序。但是在返回时,如果您有一些子活动,则可能会打开另一个未完成的活动。我将 noHistory:true 添加到我的活动中,因此返回的应用程序从 MainActivity 开始。

<activity 
      android:name=".MainActivity"
      android:noHistory="true">
</activity>

D
Daniel F

只是将一个添加到终止应用程序的残酷方法列表中:

Process.sendSignal(Process.myPid(), Process.SIGNAL_KILL);


Process.killProcess(Process.myPid()) 做同样的事情,但更短