Android之――退出多个Activity

小挽 分享 时间: 收藏本文

【简介】感谢网友“小挽”参与投稿,下面是小编给大家带来关于Android之――退出多个Activity(共7篇),一起来看看吧,希望对您有所帮助。

篇1:Android之――退出多个Activity

这里介绍两种方法:一种把每个activity记住,然后逐一干掉;另一种思路是使用广播,

方法一、用list保存activity实例,然后逐一干掉

具体代码如下:

import java.util.LinkedList;import java.util.List;import android.app.Activity;import android.app.AlertDialog;import android.app.Application;import android.content.DialogInterface;import android.content.Intent;/** * @author liuyazhuang */public class SysApplication extends Application { private List mList = new LinkedList; private static SysApplication instance; private SysApplication() {} public synchronized static SysApplication getInstance() { if (null == instance) { instance = new SysApplication(); } return instance; } // add Activity public void addActivity(Activity activity) { mList.add(activity); } public void exit() { try { for (Activity activity : mList) { if (activity != null) activity.finish(); } } catch (Exception e) { e.printStackTrace(); } finally { System.exit(0); } } @Override public void onLowMemory() { super.onLowMemory(); System.gc(); }}在每个Activity的onCreate方法中添加类似代码:

public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); SysApplication.getInstance().addActivity(this);}在需要退出程序的时候,调用:

SysApplication.getInstance().exit();

简而言之,通过单例模式把每个Activity 的引用添加到一个全局链表中,每次退出程序调用System.exit(0)时,先调用链表中Activity 的finish方法

在此,我将以上方法提炼成一个工具类,具体代码如下:

package com.lyz.android.utils;import java.util.HashMap;import java.util.Set;import android.app.Activity;/** * 一个Activity管理器管理活动的Activity。 * @author liuyazhuang * Date:-08-17 */public class ActivityTaskManager { private static ActivityTaskManager activityTaskManager = null; private HashMapactivityMap = null; private ActivityTaskManager() { activityMap = new HashMap(); } /** * 返回activity管理器的唯一实例对象。 * * @return */ public static synchronized ActivityTaskManager getInstance() { if (activityTaskManager == null) { activityTaskManager = new ActivityTaskManager(); } return activityTaskManager; } /** * 将一个activity添加到管理器。 * * @param activity */ public Activity putActivity(String name, Activity activity) { return activityMap.put(name, activity); } /** * 得到保存在管理器中的Activity对象。 * * @param name * @return */ public Activity getActivity(String name) { return activityMap.get(name); } /** * 返回管理器的Activity是否为空。 * * @return 当且当管理器中的Activity对象为空时返回true,否则返回false。 */ public boolean isEmpty() { return activityMap.isEmpty(); } /** * 返回管理器中Activity对象的个数。 * * @return 管理器中Activity对象的个数。 */ public int size() { return activityMap.size(); } /** * 返回管理器中是否包含指定的名字。 * * @param name *要查找的名字, * @return 当且仅当包含指定的名字时返回true, 否则返回false。 */ public boolean containsName(String name) { return activityMap.containsKey(name); } /** * 返回管理器中是否包含指定的Activity。 * * @param activity *要查找的Activity。 * @return 当且仅当包含指定的Activity对象时返回true, 否则返回false。 */ public boolean containsActivity(Activity activity) { return activityMap.containsValue(activity); } /** * 关闭所有活动的Activity。 */ public void closeAllActivity() { SetactivityNames = activityMap.keySet(); for (String string : activityNames) { finisActivity(activityMap.get(string)); } activityMap.clear(); } /** * 关闭所有活动的Activity除了指定的一个之外。 * * @param nameSpecified *指定的不关闭的Activity对象的名字。 */ public void closeAllActivityExceptOne(String nameSpecified) { SetactivityNames = activityMap.keySet(); Activity activitySpecified = activityMap.get(nameSpecified); for (String name : activityNames) { if (name.equals(nameSpecified)) { continue; } finisActivity(activityMap.get(name)); } activityMap.clear(); activityMap.put(nameSpecified, activitySpecified); } /** * 移除Activity对象,如果它未结束则结束它。 * * @param name *Activity对象的名字。 */ public void removeActivity(String name) { Activity activity = activityMap.remove(name); finisActivity(activity); } private final void finisActivity(Activity activity) { if (activity != null) { if (!activity.isFinishing()) { activity.finish(); } } }}

方法二、使用广播

2.2退出整个应用难免让人困扰,曾经一度的尝试一下方式:

ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);manager.killBackgroundProcesses(package);不行

android.os.Process.killProcess(android.os.Process.myPid());也不行

manager.restartPackage(package);

还是不行

Intent MyIntent = new Intent(Intent.ACTION_MAIN);MyIntent.addCategory(Intent.CATEGORY_HOME);startActivity(MyIntent);finish();

这个只是退回到桌面,如果打开多个Activity关闭重新打开也会有问题,还是还是不行

看到有说广播机制,发现是个好东东,能彻底解决这个问题,废话不说看代码:

public abstract class EnterActivity extends BaseActivity { ... // 写一个广播的内部类,当收到动作时,结束activity private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { unregisterReceiver(this); // 这句话必须要写要不会报错,不写虽然能关闭,会报一堆错 ((Activity) context).finish(); } }; @Override public void onResume() { super.onResume(); // 在当前的activity中注册广播 IntentFilter filter = new IntentFilter(); filter.addAction(Attribute.PAGENAME); registerReceiver(this.broadcastReceiver, filter); // 注册 } public void close() { Intent intent = new Intent(); intent.setAction(Attribute.PAGENAME); // 说明动作 sendBroadcast(intent);// 该函数用于发送广播 finish(); } ...}别人写的缺了个地方(unregisterReceiver)这个必须要加,不然会出一堆错,找了个最简单的方法。

篇2:Android Activity 详述

activity类处于android.app包中,继承关系:

extends ContextThemeWrapper

implements LayoutInflater.Factory2 Window.Callback KeyEvent.CallbackView.OnCreateContextMenuListenerComponentCallbacks2

java.lang.Object?android.content.Context?android.content.ContextWrapper?android.view.ContextThemeWrapper?android.app.Activity

Activity 简介

Activity是什么呢?Activity是一个应用程序提供与用户进行交流的界面,每个Activity都可以通过布局来呈现自己的用户界面,一个应用程序通常包括很多Activity,其中有一个被称为主Activity,这是程序第一次启动所展示的,例如很多程序都有的欢迎界面。将Activity设置成主Activity可以通过配置AndroidManifest.xml文件,将如下代码复制到activity的标签之中:

一个Activity可以启动另一个Activity来实现不同的表现,当一个Activity启动后,它被压入一个stack中,获得焦点,当用户按了back按钮后,当前的Activity从stack中弹出(即被destroyed),先前的Activity被释放从新获得焦点。这些涉及到Activity的生命周期,后面将进行讨论。

怎么创建一个Activity呢?通过继承父类Activity,来创建一个属于自己的Activity,这要求你需要实现Activity父类的回调方法,这些方法在Activity的生命周期中的不同状态被调用,如:创建,暂停,释放,销毁。其中有两个最重要的回调方法:

1.onCreate()

这个方法在Activity被创建时被调用,在这个方法应该初始化各个控件,通过调用setContentView(R.layout.xxx)方法定义布局来展现Activity的用户界面,其中R.layout.xxx为Activity的XML布局文件。

2.onPause()

这个方法在用户离开当前Activity时被调用,这就需要在这个方法中保存用户与当前Activity的会话,比如在EditText中输入的值。用户在返回当前Activity时,还应该显示离开时所填写的值。

当然每创建一个Activity都需要在AndroidManifest.xml文件中注册一个相应的Activity。如:创建的Activity的类名为:MyActivity则在文件中需添加如下代码:

Activity 的状态及状态间的转换:

在 android 中,Activity 拥有四种基本状态:

Active/Runing一个新 Activity 启动入栈后,它在屏幕最前端,处于栈的最顶端,此时它处于可见并可和用户交互的激活状态。Paused当 Activity 被另一个透明或者 Dialog 样式的 Activity 覆盖时的状态。此时它依然与窗口管理器保持连接,系统继续维护其内部状态,所以它仍然可见,但它已经失去了焦点故不可与用户交互。Stoped当 Activity 被另外一个 Activity 覆盖、失去焦点并不可见时处于Stoped状态。KilledActivity 被系统杀死回收或者没有被启动时处于Killed状态。

当一个 Activity 实例被创建、销毁或者启动另外一个 Activity 时,它在这四种状态之间进行转换,这种转换的发生依赖于用户程序的动作。下图说明了 Activity 在不同状态间转换的时机和条件:

图 1. Activity 的状态转换

如上所示,Android 程序员可以决定一个 Activity 的“生”,但不能决定它的“死”,也就时说程序员可以启动一个 Activity,但是却不能手动的“结束”一个 Activity。当你调用Activity.finish()方法时,结果和用户按下 BACK 键一样:告诉 Activity Manager 该 Activity 实例完成了相应的工作,可以被“回收”。随后 Activity Manager 激活处于栈第二层的 Activity 并重新入栈,同时原 Activity 被压入到栈的第二层,从 Active 状态转到 Paused 状态。例如:从 Activity1 中启动了 Activity2,则当前处于栈顶端的是 Activity2,第二层是 Activity1,当我们调用Activity2.finish()方法时,Activity Manager 重新激活 Activity1 并入栈,Activity2 从 Active 状态转换 Stoped 状态,Activity1. onActivityResult(int requestCode, int resultCode, Intent data)方法被执行,Activity2 返回的数据通过data参数返回给 Activity1。

Activity 栈

Android 是通过一种 Activity 栈的方式来管理 Activity 的,一个 Activity 的实例的状态决定它在栈中的位置。处于前台的 Activity 总是在栈的顶端,当前台的 Activity 因为异常或其它原因被销毁时,处于栈第二层的 Activity 将被激活,上浮到栈顶。当新的 Activity 启动入栈时,原 Activity 会被压入到栈的第二层。一个 Activity 在栈中的位置变化反映了它在不同状态间的转换。Activity 的状态与它在栈中的位置关系如下图所示:

图 2. Activity 的状态与它在栈中的位置关系

如上所示,除了最顶层即处在 Active 状态的 Activity 外,其它的 Activity 都有可能在系统内存不足时被回收,一个 Activity 的实例越是处在栈的底层,它被系统回收的可能性越大。系统负责管理栈中 Activity 的实例,它根据 Activity 所处的状态来改变其在栈中的位置。

Activity 生命周期

在android.app.Activity类中,Android 定义了一系列与生命周期相关的方法,在我们自己的 Activity 中,只是根据需要复写需要的方法.

Activity生命周期图:

下面我们通过一个实例来说明Activity生命周期。新建工程,编写如下代码:

public class MainActivity extends AppCompatActivity { private String TAG = MainActivity; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.i(TAG, onCreate); } @Override protected void onResume() { super.onResume(); Log.i(TAG, onResume); } @Override protected void onStart() { super.onStart(); Log.i(TAG, onStart); } @Override protected void onPause() { super.onPause(); Log.i(TAG, onPause); } @Override protected void onStop() { super.onStop(); Log.i(TAG, onStop); } @Override protected void onRestart() { super.onRestart(); Log.i(TAG, onRestart); } @Override protected void onDestroy() { super.onDestroy(); Log.i(TAG, onDestroy); }}我们通过记录操作和打印日志的方式来看看Activity的生命周期过程;

1、 运行

看到如下打印日志:

11-26 09:09:33.665 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onCreate

11-26 09:09:33.665 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onStart

11-26 09:09:33.665 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onResume

2、按下返回按键:

11-26 09:30:20.097 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onPause

11-26 09:30:20.637 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onStop

11-26 09:30:20.637 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onDestroy

3、长按Home键,弹出最近打开过的应用程序,点击ActivityDemo

11-26 09:31:07.341 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onCreate

11-26 09:31:07.341 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onStart

11-26 09:31:07.341 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onResume

4、按Home键

11-26 09:31:44.649 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onPause

11-26 09:31:45.173 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onStop

5、在AllList中点击打开

11-26 09:32:11.793 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onRestart

11-26 09:32:11.793 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onStart

11-26 09:32:11.793 24933-24933/com.jcdh.jcli.activitydemo I/MainActivity: onResume

通过日志信息,我们可以看到,

Activity的启动过程:onCreate—onStart—onResume;

下返回键时:onPause—onStop—onDestroy 正如上面说是,当按下返回键时,此Activity弹出栈,程序销毁。确实如此;

我们再次 打开时的启动过程又回到onCreate—onStart—onResume。OK;

启动之后按下Home键,回到Launcher,查看打印信息:onPause—onStop;

再次打开的运行过程:onRestart—onStart—onResume;

我们通过对Activity的各种操作,构成了Activity的生命周期,我们看到无论对Activity做如何的操作,都会接收到相关的回调方法,那么我们在开发的过程中通过这些回调方法就可以写工作,比如说释放一些重量级的对象,网络连接,数据库连接,文件读等等。

以下是各个方法的详细说明:

onCreate():当 activity 第一次创建时会被调用。在这个方法中你需要完成所有的正常静态设置 ,比如创建一个视图( view )、绑定列表的数据等等。如果能捕获到 activity 状态的话,这个方法传递进来的 Bundle 对象将存放了 activity 当前的状态。调用该方法后一般会调用 onStart() 方法。

onRestart():在 activity 被停止后重新启动时会调用该方法。其后续会调用 onStart 方法。

onStart() 当 activity 对于用户可见前即调用这个方法。如果 activity回到前台则接着调用 onResume() ,如果 activity 隐藏则调用onStop()

onResume():在 activity 开始与用户交互前调用该方法。在这时该activity 处于 activity 栈的顶部,并且接受用户的输入。其后续会调用 onPause() 方法。

onPause():在系统准备开始恢复其它 activity 时会调用该方法。这个方法中通常用来提交一些还没保存的更改到持久数据 中,停止一些动画或其它一些耗 CPU 的操作等等。无论在该方法里面进行任何操作,都需要较快速完成,因为如果它不返回的话,下一个 activity 将无法恢复出来。如果 activity 返回到前台将会调用 onResume() ,如果 activity 变得对用户不可见了将会调用onStop() 。

onStop():在 activity 对用户不可见时将调用该方法。可能会因为当前 activity 正在被销毁,或另一个 activity (已经存在的activity 或新的 activity )已经恢复了正准备覆盖它,而调用该方法。如果 activity 正准备返回与用户交互时后续会调用onRestart ,如果 activity 正在被释放则会调用 onDestroy 。

onDestroy():在 activity 被销毁前会调用该方法。这是 activity 能接收到的最后一个调用。可能会因为有人调用了 finish 方法使得当前activity 正在关闭,或系统为了保护内存临时释放这个 activity的实例,而调用该方法。你可以用 isFinishing 方法来区分这两种不同的情况。

启动另外一个 Activity

要启动一个新的Activity,我们可以通过调用 startActivity来启动例:

Intent intent =new Intent(CurrentActivity.this,OtherActivity.class); startActivity(intent);

注意:OtherActivity同样在 AndroidManifest.xml 中定义。

Activity 之间通信使用 Intent 通信

在 Android 中,不同的 Activity 实例可能运行在一个进程中,也可能运行在不同的进程中。因此我们需要一种特别的机制帮助我们在 Activity 之间传递消息。Android 中通过 Intent 对象来表示一条消息,一个 Intent 对象不仅包含有这个消息的目的地,还可以包含消息的内容,这好比一封 Email,其中不仅应该包含收件地址,还可以包含具体的内容。对于一个 Intent 对象,消息“目的地”是必须的,而内容则是可选项。

在上面的实例中通过Activity. startActivity(intent)启动另外一个 Activity 的时候,我们在 Intent 类的构造器中指定了“收件人地址”。

我们通过bundle对象来传递信息,bundle维护了一个HashMap对象,将我们的数据存贮在这个 HashMap 中来进行传递。但是像上面这样的代码稍显复杂,因为 Intent 内部为我们准备好了一个bundle,所以我们也可以使用这种更为简便的方法:

Intent intent =new Intent(MainActivity.this,OtherActivity.class); intent.putExtra(boolean_key, true); intent.putExtra(string_key, string_value); startActivity(intent);

接收:

Intent intent=getIntent(); intent.getBooleanExtra(boolean_key,false); intent.getStringExtra(string_key);

Activity 的 Intent Filter

ntent Filter 描述了一个组件愿意接收什么样的 Intent 对象,Android 将其抽象为 android.content.IntentFilter 类。在 Android 的 AndroidManifest.xml 配置文件中可以通过节点为一个 Activity 指定其 Intent Filter,以便告诉系统该 Activity 可以响应什么类型的 Intent。

当程序员使用 startActivity(intent) 来启动另外一个 Activity 时,如果直接指定 intent 了对象的 Component 属性,那么 Activity Manager 将试图启动其 Component 属性指定的 Activity。否则 Android 将通过 Intent 的其它属性从安装在系统中的所有 Activity 中查找与之最匹配的一个启动,如果没有找到合适的 Activity,应用程序会得到一个系统抛出的异常。这个匹配的过程如下:

图 4. Activity 种 Intent Filter 的匹配过程

Action 匹配

Action 匹配Action 是一个用户定义的字符串,用于描述一个 Android 应用程序组件,一个 Intent Filter 可以包含多个 Action。在 AndroidManifest.xml 的 Activity 定义时可以在其节点指定一个 Action 列表用于标示 Activity 所能接受的“动作”,例如:

……

如果我们在启动一个 Activity 时使用这样的 Intent 对象:

Intent intent =new Intent(); intent.setAction(com.zy.myaction);

那么所有的 Action 列表中包含了“com.zy.myaction”的 Activity 都将会匹配成功。

Android 预定义了一系列的 Action 分别表示特定的系统动作。这些 Action 通过常量的方式定义在android.content. Intent中,以“ACTION_”开头。我们可以在 Android 提供的文档中找到它们的详细说明。

URI 数据匹配

一个 Intent 可以通过 URI 携带外部数据给目标组件。在节点中,通过节点匹配外部数据。

mimeType 属性指定携带外部数据的数据类型,scheme 指定协议,host、port、path 指定数据的位置、端口、和路径。如下:

如果在 Intent Filter 中指定了这些属性,那么只有所有的属性都匹配成功时 URI 数据匹配才会成功。

Category 类别匹配

节点中可以为组件定义一个 Category 类别列表,当 Intent 中包含这个列表的所有项目时 Category 类别匹配才会成功。

一些关于 Activity 的技巧

锁定 Activity 运行时的屏幕方向

Android 内置了方向感应器的支持。在 G1 中,Android 会根据 G1 所处的方向自动在竖屏和横屏间切换。但是有时我们的应用程序仅能在横屏 / 竖屏时运行,比如某些游戏,此时我们需要锁定该 Activity 运行时的屏幕方向,节点的android:screenOrientation属性可以完成该项任务,示例代码如下:

// 竖屏 , 值为 landscape 时为横屏…………

全屏的 Activity

要使一个 Activity 全屏运行,可以在其onCreate()方法中添加如下代码实现:

// 设置全屏模式 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // 去除标题栏 requestWindowFeature(Window.FEATURE_NO_TITLE);

设置Activity 的 Title

setTitle(我的);

实现双击返回键退出功能:

private long exitTime = 0;@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) { if(keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN){ if((System.currentTimeMillis()-exitTime) > ){ Toast.makeText(getApplicationContext(), 再按一次退出程序, Toast.LENGTH_SHORT).show(); exitTime = System.currentTimeMillis(); } else {finish();System.exit(0); } return true; } return super.onKeyDown(keyCode, event);}

篇3:Android activity任务栈

当把Activity的allowTaskReparenting属性设置成true时,Activity就拥有了一个转移所在任务的能力,当然想具有这种神器能力的前提是taskAffinity相同,感觉跟你说完这句话突然把你推到坑里了,下面给出一个实例:app A启动app B的activity C,按home键回到桌面,当你启动app B的时候,显示的是activity C,A启动了C,C在A的任务栈中,但是C属于app B并且C的taskAffinity跟B相同,所以app B启动的时候任务栈的栈顶有个C,所以显示的就是C了

在Intent当中,有以下几个flag是比较常用的:

FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_SINGLE_TOP FLAG_ACTIVITY_CLEAR_TOP FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

篇4:Android activity任务栈

具有此标志位的activity,当它启动时,在同一个任务栈中所有位于它上面的activity都要出栈,这个模式一般需要和FLAG_ACTIVITY_NEW_TASK配合使用,在这种情况下被启动的activity如果已经存在,系统就会调用onNewIntent,

如果被启动的activity采用的是标准模式,它和它之前的activity都要出栈

篇5:Android activity任务栈

如何用户将任务切换到后台之后过了很长一段时间,系统会将这个任务中除了最底层的那个Activity之外的其它所有Activity全部清除掉。当用户重新回到这个任务的时候,最底层的那个Activity将得到恢复。这个是系统默认的行为,因为既然过了这么长的一段时间,用户很有可能早就忘记了当时正在做什么,那么重新回到这个任务的时候,基本上应该是要去做点新的事情了。

alwaysRetainTaskState clearTaskOnLaunch finishOnTaskLaunch

篇6:Android activity任务栈

具有此标志位的activity不会出现在历史activity的列表中,它等同于

android:excludeFromRecents=”true”

篇7:Android基础之退出应用程序Demo

对于Android我也不是很熟悉,只是学习一些基本内容就OK.所以写的内容也很简单.本Demo要实现的效果就是双击返回键弹出提示框确认是否退出程序.

一、废话少说直接上代码.至于涉及到的相关包在Eclipse使用快捷键CTRL+SHIFT+O即可搞定.

?

private static Boolean bExit = false;

@Override

public boolean onKeyDown(int keyCode,KeyEvent event)

{

if(keyCode == KeyEvent.KEYCODE_BACK)

{

if (bExit == false)

{

bExit = true;

final Timer TTimer = new Timer();

TTimer.schedule(new TimerTask(){ @Override public void run() {TTimer.cancel();bExit = false;}}, 2000); //如果2秒内再次按下返回键则bExit = true

}

else

{

ExitApp();

}

}

return false;

}

/*****************************************************************************************************************************************/

private void ExitApp()

{

AlertDialog dlg =

new AlertDialog.Builder(MainActivity.this).setMessage(“确定要退出本APP么”).setPositiveButton(“确定”,new DialogInterface.OnClickListener()

{

@Override

public void onClick(DialogInterface arg0,int arg1)

{

finish();

System.exit(0);

}}).setNegativeButton(“取消”,new DialogInterface.OnClickListener()

{

@Override

public void onClick(DialogInterface dialog,int arg1)

{

dialog.dismiss();

}}).create();

dlg.show();

}

}

PS:附运行效果图:双击返回键之后将弹出一个确认框如下图:

相关专题 多个android