【Android源码 栏目提醒】:以下是网学会员为您推荐的Android源码 -Android_彻底退出(关闭)应用程序 - 其它资料,希望本篇文章对您学习有所帮助。
做
android 开发时,发现一个关于
android 退出时不能彻底关闭的问题,比如:一个程序里 new 出了 N 多个 Thread,这样在退出程序的可能不能完全关闭,最后发现,只用 finish方法,有时候不能彻底退出,个人感觉还是要在适当的地方加上:System.exit0-----------------------------------------------------------------------------前言:finish:结束当前 Activity,不会立即释放内存。
遵循
android 内存管理机制。
exit:结束当前组件如 Activity,并立即释放当前 Activity 所占资源。
killProcess:结束当前组件如 Activity,并立即释放当前 Activity 所占资源。
restartPackage:结束整个 App,包括 service 等其它 Activity 组件。
1. finish方法该方法可以结束当前 Activity,但是如果你的 App 有很多 Activity 的话,使用该方法显得有点捉襟见肘了。
另外,还有一个方法 finishActivity int requestCode 关于这个方法,先看看 sdk 的api 说明吧! public voidfinishActivity int requestCode Since: APILevel 1 Force finishanother activity that you had previously started withstartActivityForResultIntent int. ParametersrequestCode The request code of the activity that you had giventostartActivityForResult. If there are multiple activities started with thisrequest code they will all be finished.也许你会这样理解 ,Activity1 通过方法 startActivityForResult Intent int 启动Activity2,然后在 Activity2 中通过方法 finishActivity intrequestCode来结束Activity1,但是很不幸运,不是这样的。
不信你可以 Demo 一把!上面文档说得很明白,该方法强制关闭通过方法 startActivityForResult Intent int启动的 Activity,也就是说在 Activity1 中的重写方法onActivityResultintrequestCode int resultCode Intent data 来接收 Activity2返回的结果,必须在 Activity1 中调用 finishActivityint requestCode来结束Activity2。
(一般在 onActivityResult 方法调用该方法结束 Activity2)。
Force finishanother activity that you had previously started withstartActivityForResultIntent int. Parameters还有,下面两个方法,可以参阅文档以及
源码研究一下。
finishActivityFromChildActivity child int requestCode finishFromChildActivity child2. killProcess通过调用
android.os.Process 的相关方法,结束 App,示例如下: btn_exit.setOnClickListenernew Button.OnClickListener Override public voidonClickView v
android.os.Process.killProcessandroid.os.Process.myPid 3. exit我们知道,Java 的 exitint code 方法可以退出程序,通过查看该方法
源码,知道它实际上是调用下面的方法: Runtime.getRuntime.exitcode示例代码,如下所示: btn_exit.setOnClickListenernew Button.OnClickListener Override public voidonClickView v System.exit0//正常退出 App 接下来,我们研究一下这个方法。
java.lang.System 这个类的该方法 jdk 说明: exit public staticvoid exitint status 终止当前正在运行的 Java 虚拟机。
参数用作状态码;根据惯例,非 0 的状态码表示异常终止。
该方法调用 Runtime 类中的 exit 方法。
该方法永远不会正常返回。
调用 System.exitn 实际上等效于调用: Runtime.getRuntime.exitn 参数: status - 退出状态。
抛出: SecurityException - 如果安全管理器存在并且其 checkExit 方法不允许以指定状态退出。
另请参见: Runtime.exitint也就是说,参数为非 0 值的话是异常退出程序。
参数为 0 的话,就是正常退出。
看 RunTime 这个类的该方法
源码: public voidexitint status SecurityManager security System.getSecurityManager if security null security.checkExitstatus Shutdown.exitstatus 其 api 说明: exit public voidexitint status 通过启动虚拟机的关闭序列,终止当前正在运行的 Java 虚拟机。
此方法从不正常返回。
可以将变量作为一个状态码;根据惯例,非零的状态码表示非正常终止。
虚拟机的关闭序列包含两个阶段。
在第一个阶段中,会以某种未指定的顺序启动所有已注册的关闭钩子hook(如果有的话),并且允许它们同时运行直至结束。
在第二个阶段中,如果已启用退出终结,则运行所有未调用的终结方法。
一旦完成这个阶段,虚拟机就会暂停。
如果在虚拟机已开始其关闭序列后才调用此方法,那么若正在运行关闭钩子,则将无限期地阻断此方法。
如果已经运行完关闭钩子,并且已启用退出终结on-exit finalization,那么此方法将利用给定的状态码(如果状态码是非零值)暂停虚拟机;否则将无限期地阻断虚拟机。
System.exit 方法是调用此方法的一种传统而便捷的方式。
参数: status - 终止状态。
按照惯例,非零的状态码表明非正常终止。
抛出: SecurityException - 如果安全管理器存在,并且其 checkExit 方法不允许存在指定的状态 另请参见: SecurityException SecurityManager.checkExitintaddShutdownHookjava.lang.Thread removeShutdownHookjava.lang.ThreadrunFinalizersOnExitboolean haltint该方法又是调用 Shutdown 这个类的 exit方法。
static voidexitint status booleanrunMoreFinalizers false synchronizedlock if status 0 runFinalizersOnExit false switch state case RUNNING:/ Initiate shutdown / state HOOKS break case HOOKS: /Stall and halt / break caseFINALIZERS: if status 0 / Haltimmediately on nonzero status / haltstatus else /Compatibility with old behavior: Run morefinalizers and then halt / runMoreFinalizers runFinalizersOnExit break ifrunMoreFinalizers runAllFinalizers haltstatus synchronizedShutdown.class / Synchronizeon the class object causing any other thread thatattempts to initiate shutdown to stall indefinitely / sequence haltstatus 其中,runAllFinalizers是一个本地方法: JNIEXPORT voidJNICALL Java_java_lang_Shutdown_runAllFinalizersJNIEnv env jclass ignored jclass cl jmethodID mid if cl env-FindClassenv java/lang/ref/Finalizer mid env-GetStaticMethodIDenv cl runAllFinalizers V env-CallStaticVoidMethodenv cl mid System.exit的参数是把退出原因返回给系统 一般来说可以是任何的整数 。
0 表示正常退出1 表示非正常 。
最后说一下 finish与 exit 方法的区别:finish是 Activity 的类方法,仅仅针对 Activity,当调用 finish时,只是将活动推向后台,并没有立即释放内存,活动的资源并没有被清理;当调用 System.exit0时,退出当前 Activity 并释放资源(内存),但是该方法不可以结束整个 App 如有多个 Activty或者有其他组件 service 等不会结束。
其实
android 的机制决定了用户无法完全退出应用,当你的 application 最长时间没有被用过的时候,
android 自身会决定将 application 关闭了。
4. restartPackage 方法 ActivityManager manager ActivityManagergetSystemServiceContext.ACTIVITY_SERVICE manager.restartPackagegetPackageName首先需要创建 ActivityManager 对象,然后调用 restartPackage方法(如果有兴趣的话,可以看
源码)。
注意:getPackageName 获得当前应用包名称,如 mark.zhang使用这种方式来退出 App,需要权限:更加详细的说明,如下: voidandroid.app.ActivityManager.restartPackageString packageName Have thesystem perform a force stop of everything associated with the given applicationpackage. All processes that share its uid will be killed all services it hasrunning stopped all activities removed etc. In addition aIntent.ACTION_PACKAGE_RESTARTED broadcast will be sent so that any of itsregistered alarms can be stopped notifications removed etc. You must holdthe permission
android.Manifest.permission.RESTART_PACKAGES to be able to callthis method. Parameters: packageNameThe name of the package to be stopped.可以看出,相同的 UID 的进程会被 kill,还会停止相关的服务以及移除所有的 Activity,并且会发送一个广播。
注意一个问题:在
android2.2 之后,该方法不可以将应用程序结束,需要使用ActivityManager 类的下面这个方法: public voidkillBackgroundProcesses String packageNameapi 文档说的很清楚: public voidrestartPackage String packageName Since: APILevel 3 This method isdeprecated. This is nowjust a wrapper for killBackgroundProcessesString the previous behavior hereis no longer available to applications because it allows them to break otherapplications by removing their alarms stopping their services etc.另外,需要使用权限:但是不管你怎么样折腾,还是无法退出 App,呜呼哀哉!这里给出一个方法: int currentVersion
android.os.Build.VERSION.SDK_INT ifcurrentVersion
android.os.Build.VERSION_CODES.ECLAIR_MR1 Intent startMain new IntentIntent.ACTION_MAIN startMain.addCategoryIntent.CATEGORY_HOME startMain.setFlagsIntent.FLAG_ACTIVITY_NEW_TASK startActivitystartMain System.exit0 else //
android2.1 ActivityManager am ActivityManagergetSystemServiceACTIVITY_SERVICE am.restartPackagegetPackageName 5. 小结finish:结束当前 Activity,不会立即释放内存。
遵循
android 内存管理机制。
exit:结束当前组件如 Activity,并立即释放当前 Activity 所占资源。
killProcess:结束当前组件如 Activity,并立即释放当前 Activity 所占资源。
restartPackage:结束整个 App,包括 service 等其它 Activity 组件。
特别注意:除了 finish方法可以调用 Activity 的生命周期方法如 onStop、onDestroy,其余三种退出 App 均不会调用 Activity 的生命周期方法。
除非,在调用这几个方法之前或者之后主动调用 Activity 的生命周期方法。
如: System.exitint onDestroy
上一篇:
Android项目代码规范
下一篇:
国际市场营销分析的留学论文