如何关闭Android应用程序?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2092951/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to close Android application?
提问by Danail
I want to close my application, so that it no longer runs in the background.
我想关闭我的应用程序,使其不再在后台运行。
How to do that? Is this good practice on Android platform?
怎么做?这是Android平台上的好习惯吗?
If I rely on the "back" button, it closes the app, but it stays in background. There is even application called "TaskKiller" just to kill those apps in the background.
如果我依赖“后退”按钮,它会关闭应用程序,但它会留在后台。甚至有一个名为“TaskKiller”的应用程序只是为了在后台杀死这些应用程序。
采纳答案by Danail
Just to answer my own question now after so much time (since CommonsWare commented on the most popular answer telling we should NOT do this):
只是为了在这么长时间后回答我自己的问题(因为 CommonsWare 评论了最流行的答案,告诉我们不应该这样做):
When I want to quit the app:
当我想退出应用程序时:
- I start my first activity (either splash screen, or whatever activity is currently at the bottom of the activity stack) with
FLAG_ACTIVITY_CLEAR_TOP
(which will quit all the other activities started after it, which means - all of them). Just make to have this activity in the activity stack (not finish it for some reason in advance). - I call
finish()
on this activity
- 我开始我的第一个活动(启动画面,或当前位于活动堆栈底部的任何活动) with
FLAG_ACTIVITY_CLEAR_TOP
(这将退出在它之后启动的所有其他活动,这意味着 - 所有活动)。只需在活动堆栈中包含此活动(由于某种原因未提前完成)。 - 我呼吁
finish()
这个活动
This is it, works quite well for me.
就是这样,对我来说效果很好。
回答by Danny Remington - OMS
Android has a mechanism in place to close an application safely per its documentation. In the last Activity that is exited (usually the main Activity that first came up when the application started) just place a couple of lines in the onDestroy() method. The call to System.runFinalizersOnExit(true)ensures that all objects will be finalized and garbage collected when the the application exits. You can also kill an application quickly via android.os.Process.killProcess(android.os.Process.myPid())if you prefer. The best way to do this is put a method like the following in a helper class and then call it whenever the app needs to be killed. For example in the destroy method of the root activity (assuming that the app never kills this activity):
Android 有一种机制可以根据其文档安全地关闭应用程序。在退出的最后一个活动(通常是应用程序启动时首先出现的主活动)中,只需在 onDestroy() 方法中放置几行。对System.runFinalizersOnExit(true)的调用确保在应用程序退出时所有对象都将被终结并被垃圾回收。 如果您愿意,您还可以通过android.os.Process.killProcess(android.os.Process.myPid())快速终止应用程序。最好的方法是在一个辅助类中放置一个如下所示的方法,然后在需要终止应用程序时调用它。例如在 root Activity 的 destroy 方法中(假设应用程序永远不会杀死这个 Activity):
Also Android will not notify an application of the HOMEkey event, so you cannot close the application when the HOMEkey is pressed. Android reserves the HOMEkey event to itself so that a developer cannot prevent users from leaving their application. However you can determine with the HOMEkey is pressed by setting a flag to true in a helper class that assumes that the HOMEkey has been pressed, then changing the flag to false when an event occurs that shows the HOMEkey was not pressed and then checking to see of the HOMEkey pressed in the onStop()method of the activity.
此外,Android 不会将HOME键事件通知应用程序,因此您无法在按下HOME键时关闭应用程序。Android 将HOME键事件保留 给自己,因此开发人员无法阻止用户离开他们的应用程序。但是你可以用确定HOME键是在假定一个辅助类标志设置为true,按下HOME键被按下,则改变标志设置为false事件发生时,显示HOME键没有被按下,然后检查活动的onStop()方法中是否按下了HOME键。
Don't forget to handle the HOMEkey for any menus and in the activities that are started by the menus. The same goes for the SEARCHkey. Below is some example classes to illustrate:
不要忘记处理任何菜单和由菜单启动的活动的HOME键。这同样适用于与搜索键。下面是一些示例类来说明:
Here's an example of a root activity that kills the application when it is destroyed:
下面是一个根活动的例子,它在应用程序被销毁时杀死它:
package android.example;
/**
* @author Danny Remington - MacroSolve
*/
public class HomeKey extends CustomActivity {
public void onDestroy() {
super.onDestroy();
/*
* Kill application when the root activity is killed.
*/
UIHelper.killApp(true);
}
}
Here's an abstract activity that can be extended to handle the HOMEkey for all activities that extend it:
这是一个抽象活动,可以扩展为处理扩展它的所有活动的HOME键:
package android.example;
/**
* @author Danny Remington - MacroSolve
*/
import android.app.Activity;
import android.view.Menu;
import android.view.MenuInflater;
/**
* Activity that includes custom behavior shared across the application. For
* example, bringing up a menu with the settings icon when the menu button is
* pressed by the user and then starting the settings activity when the user
* clicks on the settings icon.
*/
public abstract class CustomActivity extends Activity {
public void onStart() {
super.onStart();
/*
* Check if the app was just launched. If the app was just launched then
* assume that the HOME key will be pressed next unless a navigation
* event by the user or the app occurs. Otherwise the user or the app
* navigated to this activity so the HOME key was not pressed.
*/
UIHelper.checkJustLaunced();
}
public void finish() {
/*
* This can only invoked by the user or the app finishing the activity
* by navigating from the activity so the HOME key was not pressed.
*/
UIHelper.homeKeyPressed = false;
super.finish();
}
public void onStop() {
super.onStop();
/*
* Check if the HOME key was pressed. If the HOME key was pressed then
* the app will be killed. Otherwise the user or the app is navigating
* away from this activity so assume that the HOME key will be pressed
* next unless a navigation event by the user or the app occurs.
*/
UIHelper.checkHomeKeyPressed(true);
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.settings_menu, menu);
/*
* Assume that the HOME key will be pressed next unless a navigation
* event by the user or the app occurs.
*/
UIHelper.homeKeyPressed = true;
return true;
}
public boolean onSearchRequested() {
/*
* Disable the SEARCH key.
*/
return false;
}
}
Here's an example of a menu screen that handles the HOMEkey:
以下是处理HOME键的菜单屏幕示例:
/**
* @author Danny Remington - MacroSolve
*/
package android.example;
import android.os.Bundle;
import android.preference.PreferenceActivity;
/**
* PreferenceActivity for the settings screen.
*
* @see PreferenceActivity
*
*/
public class SettingsScreen extends PreferenceActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.layout.settings_screen);
}
public void onStart() {
super.onStart();
/*
* This can only invoked by the user or the app starting the activity by
* navigating to the activity so the HOME key was not pressed.
*/
UIHelper.homeKeyPressed = false;
}
public void finish() {
/*
* This can only invoked by the user or the app finishing the activity
* by navigating from the activity so the HOME key was not pressed.
*/
UIHelper.homeKeyPressed = false;
super.finish();
}
public void onStop() {
super.onStop();
/*
* Check if the HOME key was pressed. If the HOME key was pressed then
* the app will be killed either safely or quickly. Otherwise the user
* or the app is navigating away from the activity so assume that the
* HOME key will be pressed next unless a navigation event by the user
* or the app occurs.
*/
UIHelper.checkHomeKeyPressed(true);
}
public boolean onSearchRequested() {
/*
* Disable the SEARCH key.
*/
return false;
}
}
Here's an example of a helper class that handles the HOMEkey across the app:
下面是处理整个应用程序HOME键的辅助类示例:
package android.example;
/**
* @author Danny Remington - MacroSolve
*
*/
/**
* Helper class to help handling of UI.
*/
public class UIHelper {
public static boolean homeKeyPressed;
private static boolean justLaunched = true;
/**
* Check if the app was just launched. If the app was just launched then
* assume that the HOME key will be pressed next unless a navigation event
* by the user or the app occurs. Otherwise the user or the app navigated to
* the activity so the HOME key was not pressed.
*/
public static void checkJustLaunced() {
if (justLaunched) {
homeKeyPressed = true;
justLaunched = false;
} else {
homeKeyPressed = false;
}
}
/**
* Check if the HOME key was pressed. If the HOME key was pressed then the
* app will be killed either safely or quickly. Otherwise the user or the
* app is navigating away from the activity so assume that the HOME key will
* be pressed next unless a navigation event by the user or the app occurs.
*
* @param killSafely
* Primitive boolean which indicates whether the app should be
* killed safely or quickly when the HOME key is pressed.
*
* @see {@link UIHelper.killApp}
*/
public static void checkHomeKeyPressed(boolean killSafely) {
if (homeKeyPressed) {
killApp(true);
} else {
homeKeyPressed = true;
}
}
/**
* Kill the app either safely or quickly. The app is killed safely by
* killing the virtual machine that the app runs in after finalizing all
* {@link Object}s created by the app. The app is killed quickly by abruptly
* killing the process that the virtual machine that runs the app runs in
* without finalizing all {@link Object}s created by the app. Whether the
* app is killed safely or quickly the app will be completely created as a
* new app in a new virtual machine running in a new process if the user
* starts the app again.
*
* <P>
* <B>NOTE:</B> The app will not be killed until all of its threads have
* closed if it is killed safely.
* </P>
*
* <P>
* <B>NOTE:</B> All threads running under the process will be abruptly
* killed when the app is killed quickly. This can lead to various issues
* related to threading. For example, if one of those threads was making
* multiple related changes to the database, then it may have committed some
* of those changes but not all of those changes when it was abruptly
* killed.
* </P>
*
* @param killSafely
* Primitive boolean which indicates whether the app should be
* killed safely or quickly. If true then the app will be killed
* safely. Otherwise it will be killed quickly.
*/
public static void killApp(boolean killSafely) {
if (killSafely) {
/*
* Notify the system to finalize and collect all objects of the app
* on exit so that the virtual machine running the app can be killed
* by the system without causing issues. NOTE: If this is set to
* true then the virtual machine will not be killed until all of its
* threads have closed.
*/
System.runFinalizersOnExit(true);
/*
* Force the system to close the app down completely instead of
* retaining it in the background. The virtual machine that runs the
* app will be killed. The app will be completely created as a new
* app in a new virtual machine running in a new process if the user
* starts the app again.
*/
System.exit(0);
} else {
/*
* Alternatively the process that runs the virtual machine could be
* abruptly killed. This is the quickest way to remove the app from
* the device but it could cause problems since resources will not
* be finalized first. For example, all threads running under the
* process will be abruptly killed when the process is abruptly
* killed. If one of those threads was making multiple related
* changes to the database, then it may have committed some of those
* changes but not all of those changes when it was abruptly killed.
*/
android.os.Process.killProcess(android.os.Process.myPid());
}
}
}
回答by Cameron McBride
YES! You can most certainly close your application so it is no longer running in the background. Like others have commented finish()
is the Google recommended way that doesn't really mean your program is closed.
是的!您当然可以关闭您的应用程序,使其不再在后台运行。就像其他人评论finish()
的那样,Google 推荐的方式并不意味着您的程序已关闭。
System.exit(0);
That right there will close your application out leaving nothing running in the background.However,use this wisely and don't leave files open, database handles open, etc.These things would normally be cleaned up through the finish()
command.
那里将关闭您的应用程序,而不会在后台运行任何内容。但是,明智地使用它,不要打开文件,打开数据库句柄等。这些东西通常会通过finish()
命令清除。
I personally HATE when I choose Exit in an application and it doesn't really exit.
当我在应用程序中选择退出并且它并没有真正退出时,我个人很讨厌。
回答by Stephen
This is the way I did it:
这是我这样做的方式:
I just put
我只是把
Intent intent = new Intent(Main.this, SOMECLASSNAME.class);
Main.this.startActivityForResult(intent, 0);
inside of the method that opens an activity, then inside of the method of SOMECLASSNAME that is designed to close the app I put:
在打开活动的方法内部,然后在旨在关闭我放置的应用程序的 SOMECLASSNAME 方法内部:
setResult(0);
finish();
And I put the following in my Main class:
我把以下内容放在我的主类中:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == 0) {
finish();
}
}
回答by Lalit Jawale
Just write this code on your button EXIT click.
只需在您的按钮 EXIT click 上编写此代码即可。
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("LOGOUT", true);
startActivity(intent);
And in the onCreate()method of your MainActivity.classwrite below code as a first line,
在MainActivity.class的onCreate()方法中,将下面的代码写为第一行,
if (getIntent().getBooleanExtra("LOGOUT", false))
{
finish();
}
回答by Matthias
It's not possible using the framework APIs. It's at the discretion of the operating system (Android) to decide when a process should be removed or remain in memory. This is for efficiency reasons: if the user decides to relaunch the app, then it's already there without it having to be loaded into memory.
使用框架 API 是不可能的。操作系统 (Android) 可自行决定何时删除进程或保留在内存中。这是出于效率原因:如果用户决定重新启动应用程序,那么它就已经存在了,而不必将其加载到内存中。
So no, it's not onlydiscouraged, it's impossibleto do so.
所以不,它不仅不气馁,而且不可能这样做。
回答by hitesh141
For exiting app ways:
对于退出应用程序的方式:
Way 1 :
方式一:
call finish();
and override onDestroy();
. Put the following code in onDestroy()
:
调用finish();
并覆盖onDestroy();
. 将以下代码放入onDestroy()
:
System.runFinalizersOnExit(true)
or
或者
android.os.Process.killProcess(android.os.Process.myPid());
Way 2 :
方式2:
public void quit() {
int pid = android.os.Process.myPid();
android.os.Process.killProcess(pid);
System.exit(0);
}
Way 3 :
方式3:
Quit();
protected void Quit() {
super.finish();
}
Way 4 :
方式4:
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("EXIT", true);
startActivity(intent);
if (getIntent().getBooleanExtra("EXIT", false)) {
finish();
}
Way 5 :
方式5:
Sometimes calling finish()
will only exit the current activity, not the entire application. However, there is a workaround for this. Every time you start an activity
, start it using startActivityForResult()
. When you want to close the entire app, you can do something like the following:
有时调用finish()
只会退出当前活动,而不是整个应用程序。但是,有一个解决方法。每次activity
启动时,请使用startActivityForResult()
. 当您想关闭整个应用程序时,您可以执行以下操作:
setResult(RESULT_CLOSE_ALL);
finish();
Then define every activity's onActivityResult(...)
callback so when an activity
returns with the RESULT_CLOSE_ALL
value, it also calls finish()
:
然后定义每个活动的onActivityResult(...)
回调,以便当activity
返回RESULT_CLOSE_ALL
值时,它还调用finish()
:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(resultCode){
case RESULT_CLOSE_ALL:{
setResult(RESULT_CLOSE_ALL);
finish();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
回答by r1k0
Calling the finish()
method on an Activityhas your desired effect on that current activity.
finish()
在Activity上调用该方法会对当前的Activity产生您想要的效果。
回答by Andy E
This is how Windows Mobile has worked for... well... ever! Here's what Microsoft have to say on the matter:
这就是 Windows Mobile 的工作方式……嗯……永远!以下是微软对此事的看法:
http://blogs.msdn.com/windowsmobile/archive/2006/10/05/The-Emperor-Has-No-Close.aspx(is it sad that I remembered the title of the blog post all the way from 2006? I found the article on Google by searching "the emperor has no close" lol)
http://blogs.msdn.com/windowsmobile/archive/2006/10/05/The-Emperor-Has-No-Close.aspx(我从 2006 年就一直记得这篇博文的标题是不是很难过?我在谷歌上搜索“皇帝没有亲近”找到这篇文章,哈哈)
In short:
简而言之:
If the system needs more memory while the app is in the background, it'll close the app. But, if the system doesn't need more memory, the app will stay in RAM and be ready to come back quickly the next time the user needs it.
如果应用程序在后台时系统需要更多内存,它将关闭应用程序。但是,如果系统不需要更多内存,应用程序将保留在 RAM 中,并准备在用户下次需要时快速返回。
Many comments in this question at O'Reillysuggest that Android behaves in much the same way, closing applications that haven't been used for a while only when Android needs the memory they're using.
O'Reilly对这个问题的许多评论表明,Android 的行为方式大致相同,仅当 Android 需要它们正在使用的内存时才关闭一段时间未使用的应用程序。
Since this is a standard feature, then changing the behavior to forcefully close would be changing the user experience. Many users would be used to the gentle dismissal of their Android apps so when they dismiss one with the intention of returning to it after performing some other tasks, they may be rather frustrated that the state of the application is reset, or that it takes longer to open. I would stick with the standard behavior because it is what is expected.
由于这是一项标准功能,因此将行为更改为强制关闭将改变用户体验。许多用户习惯于轻柔地关闭他们的 Android 应用程序,因此当他们关闭应用程序并打算在执行一些其他任务后返回它时,他们可能会因为应用程序的状态被重置或需要更长的时间而感到沮丧打开。我会坚持标准行为,因为这是预期的。
回答by Daniel Satya
none of all above answers working good on my app
以上所有答案都不适用于我的应用
here is my working code
这是我的工作代码
on your exit button:
在您的退出按钮上:
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
ComponentName cn = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(cn);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
mainIntent.putExtra("close", true);
startActivity(mainIntent);
finish();
that code is to close any other activity and bring MainActivity on top now on your MainActivity:
该代码是关闭任何其他活动并将 MainActivity 置于 MainActivity 的顶部:
if( getIntent().getBooleanExtra("close", false)){
finish();
}