从注冊流程 分析怎样安全退出多个Activity 多种方式(附DEMO)
前言
因为一个同学问到我怎样依照一个流程走好之后回到首页。我曾经看到过4个解决方式,后来发现有做个记录和总结的必要,就写了这篇博文。
(之前看小强也写过一篇,这里通过自身的分析完整的总结一下下面6种方案,并加上一个DEMO便于大家了解大体流程)
在android的用户交互中。button触发的意图(Intent)跳转会为你又一次打开新的一个界面活动(Activity)。对于之前的界面依据需求进行摧毁(Finish())或则保留。
假设一个交互流程中。是从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)client交互中。返回首页button,因为在频繁的点击打开过多的界面(如微信查看朋友圈),返回首页就必须一个一个back回去,所有有的client为了优化用户体验,便会增加一个button返回首页(之前打开的所有关闭)。
以上几个样例都涉及到了 --- 怎样安全退出多个ACTIVITY 这个问题。
事实上。这个问题的解决方式有好多种,而且各有各的优缺点,以下就罗列出多个方案以及各个方案的优缺点所在。以便用户依据需求选择。
知识结构
首先,通过大致的思维导图罗列出了下面几个知识点,来帮助你去分析学习:
3.Application : 全局的使用
4.Activity: onActivityResult(int requestCode, int resultCode, Intent data)方法
5.栈的概念:Last-In/First-Out(LIFO) --- 后进先出的原则
6.BroadcastReceiver 广播
7.栈的引申的知识点:(1)ArrayList和LinkedList的差别
(2)android 栈和队列
以上的 (1)Activity的启动模式 (2)intent: Flags属性 (3)栈的概念
我通过一篇文章写明了他们3者的联系能够点击下面链接查看
Activity启动模式 及 Intent Flags 与 栈 的关联分析
详细方案
方案1
方法:採用FLAG_ACTIVITY_CLEAR_TOP退出整个程序(多activity)
思路:通过Intent的Flags来控制堆栈去解决
android中,每打开一个Activity,便会在栈中增加一个Activity。当该Activity被摧毁后,栈中便移除了它。而且栈中的Activity是依照开打的先后顺序依次排排列的。
Android的窗体类提供了历史栈,我们能够通过stack的原理来巧妙的实现,这里我们在A窗体打开B窗体时在Intent中直接增加标 志 Intent.FLAG_ACTIVITY_CLEAR_TOP,这样开启B时将会清除该进程空间的全部Activity。
代码:
在注冊流程最后的FourthStep.class中,点击完毕注冊点击事件
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。
优缺点:
优:使用对栈的巧妙利用,不会赞成内存无故占用等问题,个人觉得这种方法是首选。
方案2
方法:通过堆栈管理器去管理
思路:通过堆栈管理器。对Stack进的存储Activity进行操作(推入。推出,弹出)
代码:
public class StackManager {
/**
* Stack 中相应的Activity列表 (也能够写做 Stack<Activity>)
*/
private static Stack mActivityStack;
private static StackManager mInstance;
/**
* @描写叙述 获取栈管理工具
* @return ActivityManager
*/
public static StackManager getStackManager() {
if (mInstance == null) {
mInstance = new StackManager();
}
return mInstance;
}
/**
* 推出栈顶Activity
*/
public void popActivity(Activity activity) {
if (activity != null) {
activity.finish();
mActivityStack.remove(activity);
activity = null;
}
}
/**
* 获得当前栈顶Activity
*/
public Activity currentActivity() {
//lastElement()获取最后个子元素,这里是栈顶的Activity
if(mActivityStack == null || mActivityStack.size() ==0){
return null;
}
Activity activity = (Activity) mActivityStack.lastElement();
return activity;
}
/**
* 将当前Activity推入栈中
*/
public void pushActivity(Activity activity) {
if (mActivityStack == null) {
mActivityStack = new Stack();
}
mActivityStack.add(activity);
}
/**
* 弹出指定的clsss所在栈顶部的中全部Activity
* @clsss : 指定的类
*/
public void popTopActivitys(Class clsss) {
while (true) {
Activity activity = currentActivity();
if (activity == null) {
break;
}
if (activity.getClass().equals(clsss)) {
break;
}
popActivity(activity);
}
}
/**
* 弹出栈中全部Activity
*/
public void popAllActivitys() {
while (true) {
Activity activity = currentActivity();
if (activity == null) {
break;
}
popActivity(activity);
}
}
}
之后在注冊流程中的相应步骤的Activity的onCreate()中把当前Activity推入栈列表。完毕注冊流程后。弹出栈列表中流程所涉及的Activity。
优缺点:
缺:假设处理不当,easy造成不在当前界面的Activity被全局引用而摧毁不掉,内存得不到释放,从而无故占用不必要的内存。
方案3:
方法:全局记录打开的Activity或通过一个自己定义的类去管理打开的Activity
思路:通过在Application中用一个列表来记录当前所打开的Activity,依据需求去遍历finish()。
描写叙述:和方案2有点类似。
代码:
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);
}
使用流程和方法2类似。
优缺点:
缺:假设处理不当,easy造成不在当前界面的Activity被全局引用而摧毁不掉,内存得不到释放,从而无故占用不必要的内存。
方案4
方法:使用广播机制解决
思路:通过Activity创建的时候,设置监听广播,在注冊流程最后步完毕注冊时候,发送广播进行遍历finish().
描写叙述:这里我把这些广播的初始化都写在了基类BaseActivity里面。便于维护。
代码:
/**
* 初始化退出广播
*/
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中,初始化广播。之后在点击完毕注冊时候,发送广播
btn_finish.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
getApplicationContext().sendBroadcast(new Intent(INIENT_FINISH));
}
});
优缺点:
缺:开启过多的广播监听,认为会浪费资源。
方案5:
方法:通过Activity跳转中传递requestCode的之后依据onActivityResult(int
requestCode, int resultCode, Intent data)中返回的resultCode遍历关闭Activity
思路:使用startActivityForResult(intent, requestCode)方法跳转,而且通过
描写叙述:这里我把这些广播的初始化都写在了基类BaseActivity里面便于查看。
代码:
/** 关闭时候的requestCode请求码 */
public final static int FINISH_REQUESTCODE = 1;
/** 关闭时候的resultCode请求码 */
public final static int FINISH_RESULTCODE = 1;
/**
* 方法5通过回调关闭的时候用到
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
if(requestCode == FINISH_REQUESTCODE ){
if(resultCode == FINISH_RESULTCODE){
setResult(FINISH_RESULTCODE);
finish();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
之后在流程的Activity中调用带请求码的Intent跳转意图。
startActivityForResult(new Intent(getApplicationContext(), SecondStep.class),FINISH_REQUESTCODE);
在最后完毕注冊流程的时候通过下面方式返回:
btn_finish.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
setResult(FINISH_RESULTCODE);
finish();
}
});
优缺点:
方案6(不推荐)
方法:方法有人说能够使用抛出异常来退出,但是这样会影响到用户体验。所以不推荐
总结
以上便是我从注冊流程分析怎样安全退出多个ACTIVITY 的汇总总结。综上所述,博主认为方案1是最可行的方法,如有什么错误之处,望大家提出。立即改正。
源代码DEMO
最后附上源代码:下载地址
(以上方式中都已经讲到了相应的方法和代码,源代码能够更好的帮助你去体验下这几种方式的使用流程)
从注冊流程 分析怎样安全退出多个Activity 多种方式(附DEMO)的更多相关文章
- 从注册流程 分析如何安全退出多个Activity 多种方式(附DEMO)
退出Activity注册Android遍历 目录(?)[+] 前言 知识结构 具体方案 方案1 方法采用FLAG_ACTIVITY_CLEAR_TOP退出整个程序多activity 方案2 方 ...
- 从注册流程 分析如何安全退出多个Activity 多种方式(附DEMO)
前言 由于一个同学问到我如何按照一个流程走好之后回到首页,我以前看到过4个解决方案,后来发现有做个记录和总结的必要,就写了这篇博文.(之前看小强也写过一篇,这里通过自身的分析完整的总结一下以下6种 ...
- 苹果(APPLE)开发人员账号说明及注冊流程(99美元公司版/个人版及299美元企业版)
APPLE的政策是,要公布到APP STORE必须用99美元的个人版或公司版Apple Developer Programs,要在非商店外下载仅仅能使用299美元的企业版iOS Developer E ...
- 迅为4412开发板Linux驱动教程——总线_设备_驱动注冊流程具体解释
视频下载地址: 驱动注冊:http://pan.baidu.com/s/1i34HcDB 设备注冊:http://pan.baidu.com/s/1kTlGkcR 总线_设备_驱动注冊流程具体解释 • ...
- [iOS]iOS开发人员账号申请与注冊流程
郝萌主倾心贡献,尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠,支持郝萌主,捐赠数额任意.重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 游戏官方下 ...
- VLC架构及流程分析
0x00 前置信息 VLC是一个非常庞大的工程,我从它的架构及流程入手进行分析,涉及到一些很细的概念先搁置一边,日后详细分析. 0x01 源码结构(Android Java相关的暂未分析) # bui ...
- Android插件化开发之解决OpenAtlas组件在宿主的注冊问题
OpenAtlas有一个问题,就是四大组件必须在Manifest文件里进行注冊,那么就必定带来一个问题,插件中的组件都要反复在宿主中注冊.像Service,ContentProvider等组件眼下没有 ...
- boost.asio源码剖析(三) ---- 流程分析
* 常见流程分析之一(Tcp异步连接) 我们用一个简单的demo分析Tcp异步连接的流程: #include <iostream> #include <boost/asio.hpp& ...
- cinder侧挂载卷流程分析
cinder侧挂载卷流程分析,存储类型以lvm+iscsi的方式为分析基础cinder侧主要调用了三个接口1)reserve_volume: 把volume的状态改为attaching,阻止其它节点执 ...
随机推荐
- 使用jQuery播放/暂停 HTML5视频
文章来自:http://blog.okbase.net/jquery2000/archive/4485.html 我尝试用jQuery控制HTML5视频,两个视频分别在两个tab中,我希望点中tab后 ...
- php生成图片验证码
验证码主要用来防止暴力破解的方式来进行登录,下面是php中的图片验证码生成方式,废话不多说,直接上代码 /** * 生成验证码 */ function buildRandomString($type= ...
- php对象与数组互转
//对象转数组 function objectToArray($obj){ $arr = is_object($obj) ? get_object_vars($obj) : $obj; if(is_a ...
- LightOj_1079 Just another Robbery
题目链接 题意: 抢银行(这个背景最爱了), 有n家银行, 每家银行抢劫被抓的概率是p[i],你认为当你被抓的概率低于P的时候是安全的. 问, 你最多能抢劫到多少money. 思路: 抽象成背包问题, ...
- bzoj 1041: [HAOI2008]圆上的整点 本原勾股數組
1041: [HAOI2008]圆上的整点 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2027 Solved: 853[Submit][Stat ...
- DEEPIN 2014 正式版 试用体验
7月6日深度正式发布 Deepin 2014 操作系统,该系统是基于 Ubuntu 14.04 LTS 的 Linux 发行版,并搭载了多款深度开发的软件,更符合国人使用习惯.由于Deepin 201 ...
- android——彻底关闭——应用程序
最近学习做android的游戏开发时候,发现一个关于android退出时不能彻底关闭的问题,比如:一个程序里new 出了N多个Thread,这样在退出程序的可能不能完全关闭,最后发现,只用finish ...
- 通过dblink impdp导入
实验: 源数据库:10.5.129.160 dwhtest 需要导入的数据库:10.5.129.130 dwhtest 在10.5.129.130上创建DBLINK SQL> create p ...
- 如何启用Service,如何停用Service
一.步骤 第一步:继承Service类 public class SMSService extends Service { } 第二步:在AndroidManifest.xml文件中的<appl ...
- 数据结构(平衡树,树分治,暴力重构):WC 2014 紫荆花之恋
[题目描述] 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从紫荆树上长了出来. 仔细看看的话,这棵大树实际上是一个带权 ...