Activity 是一个应用组件,用户可与其提供的屏幕进行交互,以执行拨打电话、拍摄照片、发送电子邮件或查看地图等操作。 每个 Activity 都会获得一个用于绘制其用户界面的窗口。窗口通常会充满屏幕,但也可小于屏幕并浮动在其他窗口之上。
一个应用通常由多个彼此松散联系的 Activity 组成。 一般会指定应用中的某个 Activity 为“主” Activity,即首次启动应用时呈现给用户的那个 Activity。 而且每个 Activity 均可启动另一个 Activity,以便执行不同的操作。 每次新 Activity 启动时,前一 Activity 便会停止,但系统会在堆栈(“返回栈”)中保留该 Activity。 当新 Activity 启动时,系统会将其推送到返回栈上,并取得用户焦点。 返回栈遵循“后进先出”堆栈机制,因此,当用户完成当前 Activity 并按“返回” 按钮时,系统会从堆栈中将其弹出(并销毁),然后恢复前一 Activity。(任务和返回栈文档中对返回栈有更详细的阐述。)
当一个 Activity 因某个新 Activity 启动而停止时,系统会通过该 Activity 的生命周期回调方法通知其这一状态变化。Activity 因状态变化—系统是创建 Activity、停止 Activity、恢复 Activity 还是销毁 Activity— 而收到的回调方法可能有若干种,每一种回调方法都会为您提供执行与该状态变化相应的特定操作的机会。 例如,停止时,您的 Activity 应释放任何大型对象,例如网络或数据库连接。 当 Activity 恢复时,您可以重新获取所需资源,并恢复执行中断的操作。 这些状态转变都是 Activity 生命周期的一部分。
Activity 基本上以三种状态存在:
已继续:
此 Activity 位于屏幕前台并具有用户焦点。(有时也将此状态称作“运行中”。)
已暂停:
另一个 Activity 位于屏幕前台并具有用户焦点,但此 Activity 仍可见。也就是说,另一个 Activity 显示在此 Activity 上方,并且该 Activity 部分透明或未覆盖整个屏幕。 已暂停的 Activity 处于完全 Activity 状态(Activity 对象保留在内存中,它保留了所有状态和成员信息,并与窗口管理器保持连接),但在内存极度不足的情况下,可能会被系统终止。
已停止:
该 Activity 被另一个 Activity 完全遮盖(该 Activity 目前位于“后台”)。 已停止的 Activity 同样仍处于 Activity 状态(Activity 对象保留在内存中,它保留了所有状态和成员信息,但未与窗口管理器连接)。 不过,它对用户不再可见,在他处需要内存时可能会被系统终止。
如果 Activity 处于暂停或停止状态,系统可通过要求其结束(调用其 finish() 方法)或直接终止其进程,将其从内存中删除。(将其结束或终止后)再次打开 Activity 时,必须重建。
public class MainActivity extends AppCompatActivity {
private String TAG=MainActivity.class.getSimpleName();
/*
* 首次创建 Activity 时调用。 您应该在此方法中执行所有正常的静态设置— 创建视图、
* 将数据绑定到列表等等。系统向此方法传递一个 Bundle 对象,
* 其中包含 Activity 的上一状态,不过前提是捕获了该状态。
* 始终后接 onStart()。
*
* */
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "onCreate: onCreate()");
}
/*
* 在 Activity 即将对用户可见之前调用。
* 如果 Activity 转入前台,则后接 onResume(),
* 如果 Activity 转入隐藏状态,则后接 onStop()。
* */
@Override
protected void onStart() {
super.onStart();
Log.d(TAG, "onStart: onStart()");
}
/*
* 在 Activity 即将开始与用户进行交互之前调用。
* 此时,Activity 处于 Activity 堆栈的顶层,并具有用户输入焦点。
* 始终后接 onPause()。
* */
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume: onResume()");
}
/*
* 当系统即将开始继续另一个 Activity 时调用。
* 此方法通常用于确认对持久性数据的未保存更改、
* 停止动画以及其他可能消耗 CPU 的内容,诸如此类。
* 它应该非常迅速地执行所需操作,因为它返回后,下一个 Activity 才能继续执行。
* 如果 Activity 返回前台,
* 则后接 onResume(),
* 如果 Activity 转入对用户不可见状态,则后接 onStop()。
* */
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause: onPause()");
}
/*
*
* 在 Activity 已停止并即将再次启动前调用。
* 始终后接 onStart()
*
*/
@Override
protected void onRestart() {
super.onRestart();
Log.d(TAG, "onRestart: onRestart()");
}
/*
*
* Activity 对用户不再可见时调用。
* 如果 Activity 被销毁,或另一个 Activity(一个现有 Activity 或新 Activity)
* 继续执行并将其覆盖,就可能发生这种情况。
* 如果 Activity 恢复与用户的交互,则后接 onRestart(),
* 如果 Activity 被销毁,则后接 onDestroy()。
*
* */
@Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop: onStop()");
}
/*
*
* 在 Activity 被销毁前调用。这是 Activity 将收到的最后调用。
* 当 Activity 结束(有人调用 Activity 上的 finish()),
* 或系统为节省空间而暂时销毁该 Activity 实例时,可能会调用它。
* 您可以通过 isFinishing() 方法区分这两种情形。
*
* */
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy: onDestroy()");
}
}
有时,您可能需要从启动的 Activity 获得结果。在这种情况下,可以通过调用 startActivityForResult()(而非 startActivity())来启动 Activity。 要想在随后收到后续 Activity 的结果,要实现 onActivityResult() 回调方法。 当后续 Activity 完成时,它会使用 Intent 向您的 onActivityResult() 方法返回结果。
MainActivity:
{
// startActivityForResult(intent,0)启动第二个窗口,
//当第二个窗口finish()时得到SecondActivity返回的数据
Intent intent=new Intent(this,SecondActivity.class);
//设置请求码,标记启动的是哪个窗口,这里请求码为0
startActivityForResult(intent,0);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//在一个窗口中,我们可以启动多个窗体,
//这就需要一个请求码(requestCode)来
//标记启动的相应的窗口,启动的窗口可能给多个窗口做回应,
//这就需要结果码(resultCode)来标记
switch (requestCode) {
case 0:
if(resultCode == RESULT_OK){
if(data!=null){
String extra = data.getStringExtra("data");
Log.d(TAG, "onActivityResult: "+extra);
}else{
Log.d(TAG, "onActivityResult: data null");
}
}
break;
}
}
当 Activity 暂停或停止时,Activity 的状态会得到保留。 确实如此,因为当 Activity 暂停或停止时,Activity 对象仍保留在内存中 — 有关其成员和当前状态的所有信息仍处于 Activity 状态。 因此,用户在 Activity 内所做的任何更改都会得到保留,这样一来,当 Activity 返回前台(当它“继续”)时,这些更改仍然存在。
不过,当系统为了恢复内存而销毁某项 Activity 时,Activity 对象也会被销毁,因此系统在继续 Activity 时根本无法让其状态保持完好,而是必须在用户返回Activity时重建 Activity 对象。但用户并不知道系统销毁 Activity 后又对其进行了重建,因此他们很可能认为 Activity 状态毫无变化。 在这种情况下,您可以实现另一个回调方法对有关 Activity 状态的信息进行保存,以确保有关 Activity 状态的重要信息得到保留:onSaveInstanceState()。
系统会先调用 onSaveInstanceState(),然后再使 Activity 变得易于销毁。系统会向该方法传递一个 Bundle,您可以在其中使用 putString() 和 putInt() 等方法以名称-值对形式保存有关 Activity 状态的信息。然后,如果系统终止您的应用进程,并且用户返回您的 Activity,则系统会重建该 Activity,并将 Bundle 同时传递给 onCreate() 和 onRestoreInstanceState()。您可以使用上述任一方法从 Bundle 提取您保存的状态并恢复该 Activity 状态。如果没有状态信息需要恢复,则传递给您的 Bundle 是空值(如果是首次创建该 Activity,就会出现这种情况)。
例如:当手机从竖屏转换到横屏,系统是重建了一个Activity显示,不再是竖屏时的Activity,这样activity里的数据就没了,我就需要保护现场。
横屏后EditText里的数据就没了
避免这样,我可以这样做:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "onCreate: onCreate()");
//EditText edit= (EditText) findViewById(R.id.edit);
TextView textView= (TextView) findViewById(R.id.text);
if (savedInstanceState != null) {
CharSequence charSequence = savedInstanceState.getCharSequence("editText");
textView.setText(charSequence);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putCharSequence("editText","editText保存的数据");
}
无法保证系统会在销毁您的 Activity 前调用 onSaveInstanceState(),因为存在不需要保存状态的情况(例如用户使用“返回” 按钮离开您的 Activity 时,因为用户的行为是在显式关闭 Activity)。 如果系统调用 onSaveInstanceState(),它会在调用 onStop() 之前,并且可能会在调用 onPause() 之前进行调用。
不过,即使您什么都不做,也不实现 onSaveInstanceState(),Activity 类的 onSaveInstanceState() 默认实现也会恢复部分 Activity 状态。具体地讲,默认实现会为布局中的每个 View 调用相应的 onSaveInstanceState() 方法,让每个视图都能提供有关自身的应保存信息。Android 框架中几乎每个小工具都会根据需要实现此方法,以便在重建 Activity 时自动保存和恢复对 UI 所做的任何可见更改。例如,EditText 小工具保存用户输入的任何文本,CheckBox 小工具保存复选框的选中或未选中状态。您只需为想要保存其状态的每个小工具提供一个唯一的 ID(通过 android:id 属性)。如果小工具没有 ID,则系统无法保存其状态。
尽管 onSaveInstanceState() 的默认实现会保存有关您的Activity UI 的有用信息,您可能仍需替代它以保存更多信息。例如,您可能需要保存在 Activity 生命周期内发生了变化的成员值(它们可能与 UI 中恢复的值有关联,但默认情况下系统不会恢复储存这些 UI 值的成员)。
由于 onSaveInstanceState() 的默认实现有助于保存 UI 的状态, 因此如果您为了保存更多状态信息而重写该方法,应始终先调用 onSaveInstanceState() 的超类实现,然后再执行任何操作。同样,如果您替代 onRestoreInstanceState() 方法,也应调用它的超类实现,以便默认实现能够恢复视图状态。
由于无法保证系统会调用 onSaveInstanceState(),因此您只应利用它来记录 Activity 的瞬态(UI 的状态)—切勿使用它来存储持久性数据,而应使用 onPause() 在用户离开 Activity 后存储持久性数据(例如应保存到数据库的数据)。
启动模式 有 4 种 :
1.Standard: 标准的模式 -- 默认的模式
每次 收到 intent , 那么 就会 新创建 activity 的实例出来,放到 任务栈中
android:launchMode="standard"
2.SingleTop: 单一顶部模式
如果发现当前的任务栈中的栈顶是 当前activity的实例, 那么就 直接使用 当前的activity的实例, 不再新创建.
如果当前栈顶不是 当前activity的实例, 那么就 创建..
源生的 mms的 编辑短信的 activity的 启动模式就是 singleTop.. 提高用户的感受, 可以很好的提示 用户 之前还有短信没有 编辑完..
android:launchMode="singleTop"
3.SingleTask: 单一任务栈模式
表示 当前的 activity 只会在 当前的任务栈中只有一个 实例了 ,
如果再次去尝试启动当前的activity, 那么 不会再次重新创建的当前的activity实例了 ,并且 如果当再次去尝试启动当前的acitivity的时候, 当前的activity不是处于任务栈的栈顶,会清空 当前处于 activity之上的哪些acitvity
应用场景:
如果一个activity启动的时候,占用的cpu的资源非常多, 非常耗 内存, 而手机中的内存又是非常珍贵的,那么这个时候 就 建议将 这样的activity的启动模式设置为 singleTask
android:launchMode="singleTask"
4.SingleInstance: 单一实例模式
单一实例 ---- 如果某个acitvity的启动模式设置为 SingleInstance ,那么 在整个 android 手机 就只会有一个 这样的activity的实例了
对于 一些 整个系统中,永远都只存 一个同样的界面的activity 就会声明使用这种启动模式
android:launchMode="singleInstance"