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 HashMap
方法二、使用广播
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.ActivityActivity 简介
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维护了一个HashMapIntent 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 配置文件中可以通过当程序员使用 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 定义时可以在其如果我们在启动一个 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 类别匹配
一些关于 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:附运行效果图:双击返回键之后将弹出一个确认框如下图: