当一个活动进入到了停止状态,是有可能被系统回收的。那么想象 以下场景,应用中有一个活动 A,用户在活动 A的基础上启动了活动 B,活动 A就进入了 停止状态,这个时候由于系统内存不足,将活动 A回收掉了,然后用户按下 Back键返回活 动A,会出现什么情况呢?其实还是会正常显示活动A的,只不过这时并不会执行onRestart() 方法,而是会执行活动 A的 onCreate()方法,因为活动 A在这种情况下会被重新创建一次。 这样看上去好像一切正常,可是别忽略了一个重要问题,活动 A中是可能存在临时数据 和状态的。
打个比方,MainActivity 中有一个文本输入框,现在你输入了一段文字,然后 启动 NormalActivity,这时 MainActivity由于系统内存不足被回收掉,过了一会你又点击了 Back键回到 MainActivity,你会发现刚刚输入的文字全部都没了,因为 MainActivity被重新 创建了。 如果我们的应用出现了这种情况,是会严重影响用户体验的,所以必须要想想办法解决 这个问题。查阅文档可以看出,Activity中还提供了一个 onSaveInstanceState()回调方法,这 个方法会保证一定在活动被回收之前调用,因此我们可以通过这个方法来解决活动被回收时临时数据得不到保存的问题。 onSaveInstanceState()方法会携带一个 Bundle类型的参数,Bundle提供了一系列的方法 用于保存数据,比如可以使用 putString()方法保存字符串,使用 putInt()方法保存整型数据, 以此类推。每个保存方法需要传入两个参数,第一个参数是键,用于后面从 Bundle中取值, 第二个参数是真正要保存的内容。
@Override
protected void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
String tempData = "Something you just typed";
outState.putString("data_key", tempData);
}
数据是已经保存下来了,那么我们应该在哪里进行恢复呢?细心的你也许早就发现,我 们一直使用的 onCreate()方法其实也有一个 Bundle类型的参数。这个参数在一般情况下都是 null,但是当活动被系统回收之前有通过 onSaveInstanceState()方法来保存数据的话,这个参 数就会带有之前所保存的全部数据,我们只需要再通过相应的取值方法将数据取出即可。 修改 MainActivity的 onCreate()方法,如下所示:
@Override
protected void onCreate(Bundle savedInstanceState)
{ super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate");
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
if (savedInstanceState != null)
{
String tempData = savedInstanceState.getString("data_key"); Log.d(TAG, tempData);
}
…… }
默认启动的是 standard
无论当前的Acitivity是哪个,都会启动一个新的
SingleTop : 当前的Activity 若在栈顶,这不会创建新的Acitvity
SingleTask: 模式可以很好地解决重复创建栈顶活动的问题,但是正如你在上一节所 看到的,如果该活动并没有处于栈顶的位置,还是可能会创建多个活动实例的。那么有没有 什么办法可以让某个活动在整个应用程序的上下文中只存在一个实例呢?这就要借助 singleTask模式来实现了。当活动的启动模式指定为 singleTask,每次启动该活动时系统首先 会在返回栈中检查是否存在该活动的实例,如果发现已经存在则直接使用该实例,并把在这 个活动之上的所有活动统统出栈,如果没有发现就会创建一个新的活动实例
获得当前执行的是那个Activity:
Log.d("BaseActivity", getClass().getSimpleName());
如果目前你手机的界面还停留在 ThirdActivity,你会发现当前想退出程序是非常不方便 的,需要连按三次 Back键才行。按 Home键只是把程序挂起,并没有退出程序。其实这个 问题就足以引起你的思考,如果我们的程序需要一个注销或者退出的功能该怎么办呢?必须 要有一个随时随地都能退出程序的方案才行
新建一个 ActivityCollector类作为活动管理器,
代码如下所示:
public class ActivityCollector
{
public static List<Activity> activities = new ArrayList<Activity>();
public static void addActivity(Activity activity)
{
activities.add(activity);
}
public static void removeActivity(Activity activity)
{ activities.remove(activity); }
public static void finishAll()
{ for (Activity activity : activities)
{
if (!activity.isFinishing())
{ activity.finish(); }
}
}
}
每个Acitivity可以这样加
ActivityCollector.addActivity(this);
可以这样一次退出
:ActivityCollector.removeActivity(this);
在任何地方一次退出:
Button button3 = (Button) findViewById(R.id.button_3); button3.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { ActivityCollector.finishAll(); } });