安全退出当前应用程序的方法_在新公司学到的第一点
来源:互联网 发布:没有可用软件包 nginx 编辑:程序博客网 时间:2024/06/11 18:41
上家公司因为某些原因离职了,于是每天出去面试也没时间来写我的博客了,这两天结束了十来天的动荡,算是稳定下来了,又重新拾起纸笔,写上两笔。
看公司代码的时候就在想,一个维护了两年的项目势必是有他独特的地方的,于是乎,在很多小细节的地方,以前虽然也面试准备过,可是确实没写过。这些东西,可能看起来不起眼,平时没什么用,可能在某些时候避免了程序崩溃的危险呢。
比如,今天就实践一个退出很多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());
系统会将,该包下的 ,所有进程,服务,全部杀掉,就可以杀干净了,要注意加上
<uses-permission android:name=\"android.permission.RESTART_PACKAGES\"></uses-permission>
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<Activity> 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<Activity>(); } 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<Activity> 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<Activity>(); } activityList.add(acitivity); } /** 清空列表,取消引用*/ public void clearActivity(){ activityList.clear(); } /** 遍历退出所有Activity */ public void exit() { for (Activity activity : activityList) { activity.finish(); } clearActivity();//千万记得清空取消引用。 System.exit(0); }
优缺点:
缺:如果处理不当,容易造成不在当前界面的Activity被全局引用而摧毁不掉,内存得不到释放,从而无故占用不必要的内存。
5.使用广播机制解决
通过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); }
- 安全退出当前应用程序的方法_在新公司学到的第一点
- Android退出当前应用程序的方法
- android 中退出当前应用程序的方法
- Android 安全退出应用程序的方法总结
- 在公司学到的东西
- Android-完全退出当前应用程序的四种方法
- Android-完全退出当前应用程序的四种方法
- android中完全退出当前应用程序的四种方法
- Android-完全退出当前应用程序的四种方法
- android中完全退出当前应用程序的四种方法
- Android-完全退出当前应用程序的四种方法
- Android-完全退出当前应用程序的四种方法
- Android-完全退出当前应用程序的四种方法
- android中完全退出当前应用程序的四种方法
- Android-完全退出当前应用程序的四种方法
- android中完全退出当前应用程序的四种方法
- Android-完全退出当前应用程序的四种方法
- Android-完全退出当前应用程序的四种方法
- Pro Android学习笔记(一四二):触摸屏(1):MotionEvents
- MySQL约束
- Ubuntu下hadoop1.21伪分布式搭建
- WebView设置
- jvm虚拟机内部原理之概述和内存分配
- 安全退出当前应用程序的方法_在新公司学到的第一点
- 文章标题
- java中值传递和引用传递出现区别的原因
- java集合--Stack
- hihocoder[Offer收割]编程练习赛5及参考
- 请求数据并xml解析
- yii2设置ActiveForm->dropDownList->prompt_val 真正支持下拉菜单默认值
- Http 与 Https
- Android开发-使用SharedPreferences保存数据-常用操作