退出打开的全部 Activity 退出多个 Activity 汇总
2015年10月23日 周五 17:33:00 源码位置:360云盘 —— 自己的学习资料 —— Android总结过的项目 —— 退出多个Activity.rar 方案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。 优缺点: 缺:如果处理不当,容易造成不在当前界面的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类似。 优缺点: 缺:如果处理不当,容易造成不在当前界面的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中,初始化广播,之后在点击完成注册时候,发送广播 /** * 发送广播退出多个Activity */ private void sendFinish() { getApplicationContext().sendBroadcast(new Intent(INIENT_FINISH)); } 优缺点: 缺:开启过多的广播监听,觉得会浪费资源。 方案5: 方法:通过Activity跳转中传递requestCode的之后根据onActivityResult(int requestCode, int resultCode, Intent data)中返回的resultCode遍历关闭Activity 思路:使用startActivityForResult(intent, requestCode)方法跳转,并且通过 描述:这里我把这些广播的初始化都写在了基类BaseActivity里面便于查看。 代码: /** * 程序某些功能界面的基类,提供返回方法 */ public class BaseActivity extends Activity { public static ArrayList<Activity> allactivity=new ArrayList<Activity>(); //存放打开的所有界面 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); allactivity.add(this); //加打开的界面保存 } /** * 监听用户按下返回键,退出程序 */ @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if(KeyEvent.KEYCODE_BACK==keyCode){ //返回键 promptExit(this); } return super.onKeyDown(keyCode, event); } /** * 退出程序 * 点击主屏返回按钮 * 提示消息对话框,如果确定退出 * 关闭本程序所有视图 * @param context */ public void promptExit(Context context) { new AlertDialog.Builder(context) .setTitle(getString(R.string.text_LeisureLife)) .setMessage(getString(R.string.exit_program)) .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { for (Activity ac : allactivity) { if(ac!=null){ ac.finish(); } } } }) .setNegativeButton(R.string.no, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }).show(); } }