android彻底退出应用_Android-完全退出当前应用程序-新公司学习到的细节

上家公司因为某些原因离职了,于是每天出去面试也没时间来写我的博客了,这两天结束了十来天的动荡,算是稳定下来了,又重新拾起纸笔,写上两笔。

看公司代码的时候就在想,一个维护了两年的项目势必是有他独特的地方的,于是乎,在很多小细节的地方,以前虽然也面试准备过,可是确实没写过。这些东西,可能看起来不起眼,平时没什么用,可能在某些时候避免了程序崩溃的危险呢。

比如,今天就实践一个退出很多Activity的功能,在某些情况下保证安全。

借鉴一篇博客中的例子吧:(注册流程)

如果一个交互流程中,是从A开始,按照A - B - C - D - A这样的顺序进行的话,那么B,C,D这3个活动界面会根据你D中最后的操作来进行保留或是摧毁,例如

(1)注册流程中,在A界面点击注册,通过B,C,D界面完成注册后,B,C,D就随之摧毁,而如果D中注册不成功没跳转会A的话,那么B,C,D就不能摧毁,之前所填的内容也必须保留。

(2)客户端交互中,返回首页按钮,由于在频繁的点击打开过多的界面(如微信查看朋友圈),返回首页就必须一个一个back回去,所有有的客户端为了优化用户体验,便会加入一个按钮返回首页(之前打开的全部关闭)。

以上例子都涉及到了 --- 如何安全退出多个ACTIVITY 这个问题。

其实,这个问题的解决方案有好多种,并且各有各的优缺点,下面就罗列出多个方案以及各个方案的优缺点所在,以及本人所在项目采用的方案。

1. Dalvik VM的本地方法

android.os.Process.killProcess(android.os.Process.myPid()) //获取PID

System.exit(0); //常规java、c#的标准退出法,返回值为0代表正常退出

2. 任务管理器方法

首先要说明该方法运行在Android 1.5 API Level为3以上才可以,同时需要权限

ActivityManager am = (ActivityManager)getSystemService (Context.ACTIVITY_SERVICE);

am.restartPackage(getPackageName());

系统会将,该包下的 ,所有进程,服务,全部杀掉,就可以杀干净了,要注意加上

3. 我们知道Android的窗口类提供了历史栈,我们可以通过stack的原理来巧妙的实现,这里我们在A窗口打开B窗口时在Intent中直接加入标 志 Intent.FLAG_ACTIVITY_CLEAR_TOP,这样开启B时将会清除该进程空间的所有Activity。

思路:通过Intent的Flags来控制堆栈去解决

android中,每打开一个Activity,便会在栈中加入一个Activity,当该Activity被摧毁后,栈中便移除了它,并且栈中的Activity是按照开打的先后顺序依次排排列的。

Android的窗口类提供了历史栈,我们可以通过stack的原理来巧妙的实现,这里我们在A窗口打开B窗口时在Intent中直接加入标 志 Intent.FLAG_ACTIVITY_CLEAR_TOP,这样开启B时将会清除该进程空间的所有Activity。

btn_finish.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

// TODO Auto-generated method stub

Intent intent = new Intent(INTENT_METHOD_FIRST_SINGUP);

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

startActivity(intent);

}

});

其中的 INTENT_METHOD_FIRST_SINGUP 是登录界面的Intent隐式Action。

优缺点:

优:使用对栈的巧妙利用,不会造成内存无故占用等问题

4.自定义一个Actiivty 栈,道理同上,不过利用一个单例模式的Activity栈来管理所有Activity。并提供退出所有Activity的方法。代码如下:

public class ScreenManager {

private static Stack activityStack;

private static ScreenManager instance;

private ScreenManager(){

}

public static ScreenManager getScreenManager(){

if(instance==null){

instance=new ScreenManager();

}

return instance;

}

//退出栈顶Activity

public void popActivity(Activity activity){

if(activity!=null){

activity.finish();

activityStack.remove(activity);

activity=null;

}

}

//获得当前栈顶Activity

public Activity currentActivity(){

Activity activity=activityStack.lastElement();

return activity;

}

//将当前Activity推入栈中

public void pushActivity(Activity activity){

if(activityStack==null){

activityStack=new Stack();

}

activityStack.add(activity);

}

//退出栈中所有Activity

public void popAllActivityExceptOne(Class cls){

while(true){

Activity activity=currentActivity();

if(activity==null){

break;

}

if(activity.getClass().equals(cls) ){

break;

}

popActivity(activity);

}

}

}

5.全局记录打开的Activity或通过一个自定义的类去管理打开的Activity

思路:通过在Application中用一个列表来记录当前所打开的Activity,根据需求去遍历finish()。

public class AppApplication extends Application {

private static AppApplication mAppApplication;

/** 当前打开的activity列表 */

public ArrayList activityList;

@Override

public void onCreate() {

// TODO Auto-generated method stub

super.onCreate();

mAppApplication = this;

}

/** 获取Application */

public static AppApplication getApp() {

if (mAppApplication == null) {

mAppApplication = new AppApplication();

}

return mAppApplication;

}

/** 添加当前Activity 到列表中 */

public void addActivity(Activity acitivity) {

if(activityList == null){

activityList = new ArrayList();

}

activityList.add(acitivity);

}

/** 清空列表,取消引用*/

public void clearActivity(){

activityList.clear();

}

/** 遍历退出所有Activity */

public void exit() {

for (Activity activity : activityList) {

activity.finish();

}

clearActivity();//千万记得清空取消引用。

System.exit(0);

}

优缺点:

缺:如果处理不当,容易造成不在当前界面的Activity被全局引用而摧毁不掉,内存得不到释放,从而无故占用不必要的内存。

6.使用广播机制解决

通过Activity创建的时候,设置监听广播,在注册流程最后步完成注册时候,发送广播进行遍历finish().

代码:

/**

* 初始化退出广播

*/

public void initFinishReceiver() {

IntentFilter filter = new IntentFilter();

filter.addAction(INIENT_FINISH);

registerReceiver(mFinishReceiver, filter);

}

/**

* 监听是否退出的广播

*/

public BroadcastReceiver mFinishReceiver = new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

if (INIENT_FINISH.equals(intent.getAction())) {

finish();

}

}

};

在流程中的每步Activity中,初始化广播,之后在点击完成注册时候,发送广播

[java] view plain copy 在CODE上查看代码片派生到我的代码片

btn_finish.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

// TODO Auto-generated method stub

getApplicationContext().sendBroadcast(new Intent(INIENT_FINISH));

}

});

缺:开启过多的广播监听,觉得会浪费资源。

我这边采用第三种方法,如下

public void exit() {

Intent intent = new Intent();

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

intent.setClass(this, HomePageActivity.class);

intent.putExtra("exitApp", true);

Misc.startActivity(intent);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值