【OSC手机App技术解析】- Android完全退出程序

迷途d书童 发布于 2012/06/27 14:22
阅读 10K+
收藏 34
做过Android开发的人都知道,应用程序点击返回键 或者 代码显示调用了Activity.finish()方法都无法完全退出,通过任务管理工具可以看到他们还在进程中。

下面我将分享 OSChina.NET Android版客户端 完全退出程序的方法:

1. 添加权限
<uses-permission android:name="android.permission.RESTART_PACKAGES" />

2. 导入AppManager工具类
AppManager类是一个自定义的工具类,作用是将应用程序所有启动的Activity都添加到堆栈,最终退出应用程序时全部释放掉Activity。

完整的AppManager类代码:
package net.oschina.app;

import java.util.Stack;

import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;

/**
 * 应用程序Activity管理类
 * @author  liux
 */
public class AppManager {
	
	private static Stack<Activity> activityStack;
	private static AppManager instance;
	
	private AppManager(){}
	/**
	 * 单一实例
	 */
	public static AppManager getAppManager(){
		if(instance==null){
			instance=new AppManager();
		}
		return instance;
	}
	/**
	 * 添加Activity到堆栈
	 */
	public void addActivity(Activity activity){
		if(activityStack==null){
			activityStack=new Stack<Activity>();
		}
		activityStack.add(activity);
	}
	/**
	 * 获取当前Activity(堆栈中最后一个压入的)
	 */
	public Activity currentActivity(){
		Activity activity=activityStack.lastElement();
		return activity;
	}
	/**
	 * 结束当前Activity(堆栈中最后一个压入的)
	 */
	public void finishActivity(){
		Activity activity=activityStack.lastElement();
		if(activity!=null){
			activity.finish();
			activity=null;
		}
	}
	/**
	 * 结束指定的Activity
	 */
	public void finishActivity(Activity activity){
		if(activity!=null){
			activityStack.remove(activity);
			activity.finish();
			activity=null;
		}
	}
	/**
	 * 结束指定类名的Activity
	 */
	public void finishActivity(Class<?> cls){
		for (Activity activity : activityStack) {
			if(activity.getClass().equals(cls) ){
				finishActivity(activity);
			}
		}
	}
	/**
	 * 结束所有Activity
	 */
	public void finishAllActivity(){
		for (int i = 0, size = activityStack.size(); i < size; i++){
            if (null != activityStack.get(i)){
            	activityStack.get(i).finish();
            }
	    }
		activityStack.clear();
	}
	/**
	 * 退出应用程序
	 */
	public void AppExit(Context context) {
		try {
			finishAllActivity();
			ActivityManager activityMgr= (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
			activityMgr.restartPackage(context.getPackageName());
			System.exit(0);
		} catch (Exception e) {	}
	}
}

3. 使用AppManager工具类
Activity启动时,在的onCreate方法里面,将该Activity实例添加到AppManager的堆栈
AppManager.getAppManager().addActivity(this);
需要退出程序时,调用
AppManager.getAppManager().AppExit(this);

如果大家有什么疑问的话,欢迎在下面回帖一起探讨。

PS:

OSC Android客户端下载地址: http://www.oschina.net/uploads/osc.apk
OSC iPhone客户端下载地址:
http://www.oschina.net/uploads/osc.ipa
OSC Windows Phone客户端下载地址: http://www.oschina.net/uploads/osc.xap

加载中
0
小杨阿哥哥
小杨阿哥哥
没有开发过android的东西!先收藏了。
0
shikeaiDev
shikeaiDev

完全退出,光靠关闭activity是不完全的。如果有长时间没关闭或删除的资源存在,task 同样不会end。osc的确做到彻底关闭,但是是个巧合,因为貌似没地方有长引用的没关闭资源。而且android的硬件平台太多,有可以自动处理掉未关闭资源,而也有不能的。

所以,退出对话框, 

个人认为!没必要,没用, 没指导性(误导使用者),没android风格。

但是这个类定义的不错。如果能跟踪app所有使用资源,那么就更接近需求。

shikeaiDev
shikeaiDev
@迷途d书童 @迷途d书童 就是这意思,所以完全退出的选项是没意义的。如果其他task of app有利用本task资源时,会造成crash.
迷途d书童
迷途d书童
确实,只靠关闭activity是不能完全退出的,这里只是释放了activity,还有其他未释放的资源通过重启安装包后调用System.exit(0);才能完全退出。
0
cokey
cokey

finishActivity方法有隐患,如果一个activity正在finish,还未完毕时调用该方法,会出现异常,应该加上activity.isFinishing的判断

迷途d书童
迷途d书童
你说的确实有这方面的可能。
0
0
shikeaiDev
shikeaiDev

引用来自“cokey”的答案

finishActivity方法有隐患,如果一个activity正在finish,还未完毕时调用该方法,会出现异常,应该加上activity.isFinishing的判断

不过,这样连环退出activities的方法,可以forground service配合,使task长时间挂起。

个人想法:

1。取消退出对话框

2。 换用 “是否挂起”选项。yes.则启动forground service。但是两者都事后调用这个mgr。因为事实上,不能保证task一定被end。

0
单链DNA
单链DNA
我退出采用方法是,所有activity都继承一个baseactivity,在baseactivity中注册一个广播接收器,接收到广播,然后就调用finish方法。
西木
西木
思路不错
0
张玉伟
张玉伟
android.os.Process.killProcess(android.os.Process.myPid());
0
s
stillhere
这、不是有点违背Android本身的特性么、驻留在后台的Activity就是为了用户再次进入时能快速的调出来,如果系统发现内存不够用自然就会回收这些个Activity了不是么、、、
茶码古道
茶码古道
@迷途d书童 同意书童先生说的
迷途d书童
迷途d书童
你说的是一方面,但是还是有不少用户就要完全退出,不想留进程在后台。
0
Simtice
Simtice
<uses-permission android:name="android.permission.RESTART_PACKAGES" />

我不加这个权限而是单单使用这个工具类照样可以退出程序,但不知道是不是真正的退出了,能否解释下这个权限加与否的区别呢?
0
y
ytxxj
此方法会产生内存泄漏,建议慎用。
返回顶部
顶部