对于一个应用程序可能有很多个Activity,可能每个人并不想一个个的去关闭Activity,也有可能忘了,那怎么关闭所有的未关闭的Activity呢,其实有很多方法,但是我最喜欢的一种就是通过广播事件去关闭,这样简单易懂,方便操作,很快捷。
首先就是建立一个父类,让所有的activity继承父类,这样就不用每次都去注册广播,只要在父类注册好就行了,代码如下:
- package net.loonggg.test;
- import android.app.Activity;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- public class BaseActivity extends Activity {
- /**
- * 关闭Activity的广播,放在自定义的基类中,让其他的Activity继承这个Activity就行
- */
- protected BroadcastReceiver finishAppReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- finish();
- }
- };
- @Override
- public void onResume() {
- super.onResume();
- // 在当前的activity中注册广播
- IntentFilter filter = new IntentFilter();
- filter.addAction("net.loonggg.exitapp");
- this.registerReceiver(this.finishAppReceiver, filter);
- }
- @Override
- protected void onDestroy() {
- super.onDestroy();
- this.unregisterReceiver(this.finishAppReceiver);
- }
- }
- package net.loonggg.test;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.KeyEvent;
- import android.view.View;
- import android.widget.Button;
- import android.widget.Toast;
- public class MainActivity extends BaseActivity {
- private Button btn;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- btn = (Button) findViewById(R.id.btn);
- btn.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent(getApplicationContext(),
- SecondActivity.class);
- startActivity(intent);
- }
- });
- }
- private long exitTime = 0;
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (KeyEvent.KEYCODE_BACK == keyCode) {
- // 判断是否在两秒之内连续点击返回键,是则退出,否则不退出
- if (System.currentTimeMillis() - exitTime > 2000) {
- Toast.makeText(getApplicationContext(), "再按一次退出程序",
- Toast.LENGTH_SHORT).show();
- // 将系统当前的时间赋值给exitTime
- exitTime = System.currentTimeMillis();
- } else {
- exitApp();
- }
- return true;
- }
- return super.onKeyDown(keyCode, event);
- }
- /**
- * 退出应用程序的方法,发送退出程序的广播
- */
- private void exitApp() {
- Intent intent = new Intent();
- intent.setAction("net.loonggg.exitapp");
- this.sendBroadcast(intent);
- }
- @Override
- protected void onDestroy() {
- super.onDestroy();
- System.out.println("-------MainActivity-------->onDestroy()");
- }
- }
- /**
- * 记录标记时间
- */
- private long exitTime = 0;
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (KeyEvent.KEYCODE_BACK == keyCode) {
- // 判断是否在两秒之内连续点击返回键,是则退出,否则不退出
- if (System.currentTimeMillis() - exitTime > 2000) {
- Toast.makeText(getApplicationContext(), "再按一次退出程序",
- Toast.LENGTH_SHORT).show();
- // 将系统当前的时间赋值给exitTime
- exitTime = System.currentTimeMillis();
- } else {
- exitApp();
- }
- return true;
- }
- return super.onKeyDown(keyCode, event);
- }
到这里就完了!非常简单吧!
现在许多应用都有一个“再按一次退出”的效果,其实实现这个不难,具体可以看我的另外一篇文章:http://maosidiaoxian.iteye.com/blog/1403040
不过最近又对以前写的东西再次封装,原因是以前是写死了,一定是“再次一次退出”的效果,而没有“再按一次XXX”的。而出现这个需求是因为最近在写的一个小的游戏应用,有“新游戏”的按钮,我觉得在响应这个事件时先弹出一个对话框来确认是否开始新游戏没什么必要,因为频率比较高,久了用户会很烦。朋友说可以做成“再按一次开始新游戏”。
于是封装了“再次一次XXX”的代码。具体如下:
- /*
- * @(#)DoubleClick.java Project:com.sinaapp.msdxblog.androidkit
- * Date:2012-3-20
- *
- * Copyright (c) 2011 CFuture09, Institute of Software,
- * Guangdong Ocean University, Zhanjiang, GuangDong, China.
- * All rights reserved.
- */
- package com.sinaapp.msdxblog.androidkit.ui.util;
- import android.content.Context;
- import android.os.Handler;
- import android.os.HandlerThread;
- import android.widget.Toast;
- /**
- * @author Geek_Soledad (66704238@51uc.com)
- */
- public abstract class DoubleClick {
- protected Context mContext;
- private boolean willDo;
- private Runnable task = new Runnable() {
- @Override
- public void run() {
- willDo = false;
- }
- };
- public DoubleClick(Context context) {
- mContext = context;
- }
- /**
- * 当某个动作要双击才执行时,调用此方法。
- *
- * @param delayTime
- * 判断双击的时间。
- * @param msg
- * 当第一次点击时,弹出的提示信息。如果为null,则不作提示。
- */
- public void doDoubleClick(int delayTime, String msg) {
- if (willDo) {
- doOnDoubleClick();
- } else {
- keepInDelayTime(delayTime);
- showMsgInToast(delayTime, msg);
- }
- }
- /**
- * 在双击之后执行的事情。
- */
- abstract protected void doOnDoubleClick();
- /**
- * 判断是否双击。
- *
- * @param delayTime
- * 是否双击的判断时间。
- */
- final private void keepInDelayTime(int delayTime) {
- willDo = true;
- HandlerThread thread = new HandlerThread("doTask");
- thread.start();
- new Handler(thread.getLooper()).postDelayed(task, delayTime);
- }
- /**
- * 显示提示信息。
- *
- * @param msg
- * 要显示的信息。
- */
- private void showMsgInToast(int delayTime, String msg) {
- if (msg != null) {
- Toast.makeText(mContext, msg, delayTime).show();
- }
- }
- }
然后关于再按一次退出,仅需要继承以上类并实现其抽象方法即可。
- /**
- * 在双击之后执行的事情。
- */
- abstract protected void doOnDoubleClick();
以下是“再次一次退出”的再次封装。不过这里我用的是单例模式,一个是我觉得对于一个应用,退出也就完了,所以它对应的这个“再次一次退出”的辅助类也是只有一个的,另一个是单例模式的话,我不需要为它写个成员变量,再在一开始的时候对它初始化,对我原来的代码影响很小。代码如下:
- /*
- * @(#)ExitDoubleClick.java Project:com.sinaapp.msdxblog.androidkit
- * Date:2012-3-20
- *
- * Copyright (c) 2011 CFuture09, Institute of Software,
- * Guangdong Ocean University, Zhanjiang, GuangDong, China.
- * All rights reserved.
- */
- package com.sinaapp.msdxblog.androidkit.ui.util;
- import android.app.Activity;
- import android.content.Context;
- /**
- * 双击退出Activity的类。
- *
- * @author Geek_Soledad (66704238@51uc.com)
- */
- public class ExitDoubleClick extends DoubleClick {
- private static ExitDoubleClick exitDoubleClick;
- private ExitDoubleClick(Context context) {
- super(context);
- }
- /**
- * 返回一个双击退出的实例。
- *
- * @param context
- * @return ExitDoubleClick
- */
- public static synchronized ExitDoubleClick getInstance(Context context) {
- if (exitDoubleClick == null) {
- exitDoubleClick = new ExitDoubleClick(context);
- }
- return exitDoubleClick;
- }
- /**
- * 双击之后退出。
- */
- @Override
- protected void doOnDoubleClick() {
- ((Activity) mContext).finish();
- exitDoubleClick = null;
- }
- /* (non-Javadoc)
- * @see com.sinaapp.msdxblog.androidkit.util.DoubleClick#doDoubleClick(int, java.lang.String)
- */
- @Override
- public void doDoubleClick(int delayTime, String msg) {
- if (msg == null || msg.equals("")) {
- msg = "再按一次退出";
- }
- super.doDoubleClick(delayTime, msg);
- }
- }
注意,在退出之后需要对exitDoubleClick赋值为null(或者可以调用System.exit(0)方法?),否则在下次启动时可能无法正常退出,因为这时调用的mContext已经不是当前的Activity实例了,所以无法对当前的Activity实例用finish()退出。