转于:http://www.eoeandroid.com/home.php?mod=space&uid=588465&do=blog&id=2667
---------------------------------------------------------------------------------------------------------------------------
做Android开发时,发现一个关于android退出时不能彻底关闭的问题,比如:一个程序里new 出了N多个Thread,这样在退出程序的可能不能完全关闭,最后发现,只用finish()方法,有时候不能彻底退出,个人感觉还是要在适当的地方加上:System.exit(0);
-=====-=-=-=-=-=======-----=====
1. finish()方法
该方法可以结束当前 Activity,但是如果你的App有很多 Activity 的话,使用该方法显得有点捉襟见肘了。
另外,还有一个方法finishActivity (int requestCode) ,关于这个方法,先看看sdk的api说明吧!
- public void finishActivity (int requestCode)
- Since: API Level 1
- Force finish another activity that you had previously started with startActivityForResult(Intent, int).
- Parameters requestCode The request code of the activity that you had given to startActivityForResult(). If there are multiple activities started with this request code, they will all be finished.
也许你会这样理解 ,Activity1 通过方法 startActivityForResult (Intent, int) 启动 Activity2,然后在 Activity2 中通过方法finishActivity (int requestCode)来结束 Activity1,但是很不幸运,不是这样的。不信你可以Demo一把!
上面文档说得很明白,该方法强制关闭通过方法 startActivityForResult (Intent, int) 启动的 Activity,也就是说在 Activity1 中的(重写)方法onActivityResult(int requestCode, int resultCode, Intent data) 来接收 Activity2 返回的结果,必须在 Activity1 中调用finishActivity (int requestCode)来结束 Activity2。(一般在onActivityResult 方法调用该方法结束 Activity2)。
- Force finish another activity that you had previously started with startActivityForResult(Intent, int).
- Parameters
还有,下面两个方法,可以参阅文档以及源码研究一下。
- finishActivityFromChild(Activity child, int requestCode)
- finishFromChild(Activity child)
2. killProcess
通过调用 android.os.Process 的相关方法,结束 App,示例如下:
- btn_exit.setOnClickListener(new Button.OnClickListener() {
- @Override
- public void onClick(View v) {
- android.os.Process.killProcess(android.os.Process.myPid());
- }
- });
3. exit
我们知道,Java 的 exit(int code) 方法可以退出程序,通过查看该方法源码,知道它实际上是调用下面的方法:
- Runtime.getRuntime().exit(code);
示例代码,如下所示:
- btn_exit.setOnClickListener(new Button.OnClickListener() {
- @Override
- public void onClick(View v) {
- System.exit(0);//正常退出App
- }
- });
接下来,我们研究一下这个方法。java.lang.System这个类的该方法jdk说明:
- exit
- public static void exit(int status)
- 终止当前正在运行的 Java 虚拟机。参数用作状态码;根据惯例,非 0 的状态码表示异常终止。
- 该方法调用 Runtime 类中的 exit 方法。该方法永远不会正常返回。
- 调用 System.exit(n) 实际上等效于调用:
- Runtime.getRuntime().exit(n)
- 参数:
- status - 退出状态。
- 抛出:
- SecurityException - 如果安全管理器存在并且其 checkExit 方法不允许以指定状态退出。
- 另请参见:
- Runtime.exit(int)
也就是说,参数为非0值的话是异常退出程序。参数为0的话,就是正常退出。
看RunTime这个类的该方法源码:
- public void exit(int status) {
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- security.checkExit(status);
- }
- Shutdown.exit(status);
- }
其api说明:
- exit
- public void exit(int status)
- 通过启动虚拟机的关闭序列,终止当前正在运行的 Java 虚拟机。此方法从不正常返回。可以将变量作为一个状态码;根据惯例,非零的状态码表示非正常终止。
- 虚拟机的关闭序列包含两个阶段。在第一个阶段中,会以某种未指定的顺序启动所有已注册的关闭钩子 (hook)(如果有的话),并且允许它们同时运行直至结束。在第二个阶段中,如果已启用退出终结,则运行所有未调用的终结方法。一旦完成这个阶段,虚拟机就会暂停。
- 如果在虚拟机已开始其关闭序列后才调用此方法,那么若正在运行关闭钩子,则将无限期地阻断此方法。如果已经运行完关闭钩子,并且已启用退出终结 (on-exit finalization),那么此方法将利用给定的状态码(如果状态码是非零值)暂停虚拟机;否则将无限期地阻断虚拟机。
- System.exit 方法是调用此方法的一种传统而便捷的方式。
- 参数:
- status - 终止状态。按照惯例,非零的状态码表明非正常终止。
- 抛出:
- SecurityException - 如果安全管理器存在,并且其 checkExit 方法不允许存在指定的状态
- 另请参见:
- SecurityException, SecurityManager.checkExit(int), addShutdownHook(java.lang.Thread), removeShutdownHook(java.lang.Thread), runFinalizersOnExit(boolean), halt(int)
该方法又是调用Shutdown这个类的exit()方法。
- static void exit(int status) {
- boolean runMoreFinalizers = false;
- synchronized (lock) {
- if (status != 0) runFinalizersOnExit = false;
- switch (state) {
- case RUNNING: /* Initiate shutdown */
- state = HOOKS;
- break;
- case HOOKS: /* Stall and halt */
- break;
- case FINALIZERS:
- if (status != 0) {
- /* Halt immediately on nonzero status */
- halt(status);
- } else {
- /* Compatibility with old behavior:
- * Run more finalizers and then halt
- */
- runMoreFinalizers = runFinalizersOnExit;
- }
- break;
- }
- }
- if (runMoreFinalizers) {
- runAllFinalizers();
- halt(status);
- }
- synchronized (Shutdown.class) {
- /* Synchronize on the class object, causing any other thread
- * that attempts to initiate shutdown to stall indefinitely
- */
- sequence();
- halt(status);
- }
- }
其中,runAllFinalizers()是一个本地方法:
- JNIEXPORT void JNICALL
- Java_java_lang_Shutdown_runAllFinalizers(JNIEnv *env, jclass ignored)
- {
- jclass cl;
- jmethodID mid;
- if ((cl = (*env)->FindClass(env, "java/lang/ref/Finalizer"))
- && (mid = (*env)->GetStaticMethodID(env, cl,
- "runAllFinalizers", "()V"))) {
- (*env)->CallStaticVoidMethod(env, cl, mid);
- }
- }
System.exit()的参数是把退出原因返回给系统, 一般来说可以是任何的整数 。
0表示正常退出,1表示非正常 。
最后说一下finish()与exit方法的区别:
finish()是Activity的类方法,仅仅针对Activity,当调用finish()时,只是将活动推向后台,并没有立即释放内存,活动的资源并没有被清理;当调用System.exit(0)时,退出当前Activity并释放资源(内存),但是该方法不可以结束整个App如有多个Activty或者有其他组件service等不会结束。
其实android的机制决定了用户无法完全退出应用,当你的application最长时间没有被用过的时候,android自身会决定将application关闭了。
4. restartPackage方法
- ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
- manager.restartPackage(getPackageName());
首先需要创建ActivityManager对象,然后调用restartPackage()方法(如果有兴趣的话,可以看源码)。
注意:getPackageName获得当前应用包名称,如mark.zhang
使用这种方式来退出App,需要权限:
- <uses-permission android:name="android.permission.RESTART_PACKAGES" />
更加详细的说明,如下:
- void android.app.ActivityManager.restartPackage(String packageName)
- Have the system perform a force stop of everything associated with the given application package. All processes that share its uid will be killed, all services it has running stopped, all activities removed, etc. In addition, a Intent.ACTION_PACKAGE_RESTARTED broadcast will be sent, so that any of its registered alarms can be stopped, notifications removed, etc.
- You must hold the permission android.Manifest.permission.RESTART_PACKAGES to be able to call this method.
- Parameters:
- packageName The name of the package to be stopped.
可以看出,相同的UID的进程会被kill,还会停止相关的服务以及移除所有的Activity,并且会发送一个广播。
注意一个问题:在android2.2之后,该方法不可以将应用程序结束,需要使用ActivityManager类的下面这个方法:
- public void killBackgroundProcesses (String packageName)
api 文档说的很清楚:
- public void restartPackage (String packageName)
- Since: API Level 3
- This method is deprecated.
- This is now just a wrapper for killBackgroundProcesses(String); the previous behavior here is no longer available to applications because it allows them to break other applications by removing their alarms, stopping their services, etc.
另外,需要使用权限:
- <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
但是不管你怎么样折腾,还是无法退出App,呜呼哀哉!这里给出一个方法:
- int currentVersion = android.os.Build.VERSION.SDK_INT;
- if (currentVersion > android.os.Build.VERSION_CODES.ECLAIR_MR1) {
- Intent startMain = new Intent(Intent.ACTION_MAIN);
- startMain.addCategory(Intent.CATEGORY_HOME);
- startMain.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- startActivity(startMain);
- System.exit(0);
- } else {// android2.1
- ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
- am.restartPackage(getPackageName());
- }
关于android.os.Build.VERSION.SDK_INT,可以参考 http://blog.csdn.net/androidbluetooth/article/details/6778422
5. 小结
finish():结束当前Activity,不会立即释放内存。遵循android内存管理机制。
exit():结束当前组件如Activity,并立即释放当前Activity所占资源。
killProcess():结束当前组件如Activity,并立即释放当前Activity所占资源。
restartPackage():结束整个App,包括service等其它Activity组件。
特别注意:除了finish()方法可以调用Activity的生命周期方法如onStop()、onDestroy(),其余三种退出App均不会调用Activity的生命周期方法。除非,在调用这几个方法之前或者之后主动调用Activity的生命周期方法。如:
- System.exit(int);
- onDestroy();
相关推荐
Android彻底退出应用程序.doc
在Android开发中,完全退出应用程序并不像在桌面操作系统中简单地关闭窗口那样直观。由于Android的设计理念强调用户体验和后台进程的高效利用,因此系统通常不会允许应用自行彻底退出,而是将其保留在内存中以便快速...
在Android开发中,退出应用程序是一个常见的需求,尤其是在某些特定的应用场景下,用户可能希望完全关闭应用,而不是简单地退回到后台。本示例"退出Android应用程序Demo"将讲解如何实现这个功能,涉及到的关键知识点...
在Android应用开发中,"离开应用程序"通常指的是提供一个机制让用户能够完全关闭或退出应用程序。这个功能虽然在现代Android系统中并不强制要求,因为系统会自动管理应用的生命周期,但有时候用户可能还是希望有一个...
在Android应用开发中,完全退出程序意味着结束所有与应用程序相关的活动(Activity)并释放系统资源。用户通常期望点击“退出”按钮后,整个应用程序能够完全关闭,而不是仅仅停留在后台运行。下面我们将详细讨论...
在Android开发中,退出整个应用是一项常见的需求,尤其是在用户完成所有操作后希望彻底退出应用时。这个主题主要涉及Android应用程序的生命周期、Activity栈管理和进程管理。以下是对这一问题的详细阐述: 首先,...
在Android应用开发中,用户可能需要在完成一系列操作后彻底退出程序,特别是在处理完敏感信息或者需要节省系统资源的情况下。通常,一个Android应用由多个Activity组成,每个Activity代表一个独立的屏幕或功能。当...
在Android操作系统中,退出应用程序并不是一个直接明了的过程,因为Android设计时考虑了资源管理和用户体验。通常情况下,用户点击返回键或应用切换器中的“关闭”按钮,应用并不会立即结束,而是进入后台运行状态。...
有一种需要,我们在菜单项中点击退出应用程序,应用程序就退出,不需要回到MainActivity设计:有两个应用界面MainActivity和BActivity,以及用于程序的通用类ExitUtil 步骤: 1、添加一个类,名为ExitUtil 代码如下:...
在Android应用开发中,完全退出应用程序并不像在其他操作系统中那样简单,因为Android系统的设计理念是尽可能保持应用的后台状态,以便用户能快速恢复到之前的状态。然而,有些情况下开发者可能需要提供一个完全退出...
在Android系统中,当用户点击应用的返回按钮或者调用`finish()`方法时,当前活动(Activity)会被销毁,但这并不意味着整个应用程序进程被完全结束。实际上,Android系统为了优化性能,可能会保持应用的部分或全部...
在Android应用开发中,完全退出程序是一个常见的需求,特别是在用户希望彻底关闭应用并释放系统资源时。本资料包“Android应用源码完全退出程序的方法.zip”聚焦于如何在Android应用程序中实现这一功能。以下是关于...
在Android开发中,有时候我们需要实现一种功能:当用户执行特定操作时,比如点击退出按钮,能够一次性关闭所有打开的Activity并退出应用程序。这种方式在一些需要快速释放资源、彻底结束程序的应用场景中较为常见。...
在Android应用开发中,完全退出程序是一个常见的需求,特别是在用户希望彻底关闭应用,释放系统资源时。本项目提供了一个Android应用源码示例,适用于毕业设计或深入理解Android应用程序生命周期的学习。下面将详细...
通过上述方法,我们可以有效地实现Android应用程序的完美退出。这种方式不仅能够确保所有的`Activity`都被正确关闭,还能根据不同的需求选择合适的退出策略。此外,通过使用单例模式来管理全局状态,使得整个实现...
在Android开发中,退出应用程序并非一个简单的行为,因为Android系统设计的理念是不允许用户直接退出应用程序,而是通过系统自身的任务管理器来管理应用的生命周期。然而,有些情况下开发者可能需要提供一个明确的...
Android应用程序在开发过程中可能会引入多种安全漏洞,这些漏洞往往是由于开发者的疏忽或对Android系统安全机制缺乏深入了解导致的。以下是一些Android应用程序中常见的潜在安全漏洞及其相关知识点。 1. 不安全的...