什么是 Android 活动的生命周期?为什么在初始化期间会调用许多听起来相似的方法(onCreate()
、onStart()
、onResume()
),而在结束时会调用许多其他方法(onPause()
、onStop()
、onDestroy()
)?
这些方法在何时被调用,应该如何正确使用它们?
什么是 Android 活动的生命周期?为什么在初始化期间会调用许多听起来相似的方法(onCreate()
、onStart()
、onResume()
),而在结束时会调用许多其他方法(onPause()
、onStop()
、onDestroy()
)?
这些方法在何时被调用,应该如何正确使用它们?
在 Activity 生命周期(Android 开发者官网)中查看。
当 Activity 第一次创建时调用。这里是进行所有正常的静态设置的地方:创建视图,将数据绑定到列表等。如果存在先前冻结的状态,则此方法还提供了一个包含该状态的 Bundle。始终紧随 onStart()。
在 Activity 停止后再次启动之前调用。始终紧随 onStart()。
当 Activity 对用户可见时调用。如果 Activity 进入前台,则紧随其后的是 onResume()。
当 Activity 开始与用户交互时调用。此时,您的 Activity 位于活动堆栈的顶部,并且用户输入将发送到该 Activity。始终紧随 onPause()。
作为 Activity 生命周期的一部分,当一个 Activity 进入后台但尚未被销毁时调用,它是 onResume() 的对应方法。当 Activity B 在 Activity A 前面启动时,将在 A 上调用此回调。B 将不会创建,直到 A 的 onPause() 返回,因此请确保此处不要做任何长时间的操作。
当您对用户不再可见时调用。接下来,根据稍后的用户活动,您将收到 onRestart()、onDestroy() 或什么都不收到的通知。请注意,在低内存情况下,如果系统没有足够的内存使 Activity 的进程在其 onPause() 方法被调用后继续运行,则可能永远不会调用此方法。
在 Activity 销毁之前的最后一个调用。这可能是因为 Activity 即将结束(有人在其上调用了 finish() 方法),或者是因为系统暂时销毁该 Activity 实例以节省空间。您可以使用 isFinishing() 方法区分这两种情况。
当 Activity 第一次加载时,以下事件会被调用:
onCreate()
onStart()
onResume()
当您点击电话按钮时,活动将进入后台,并调用以下事件:
onPause()
onStop()
退出电话拨号器,以下事件将被调用:
onRestart()
onStart()
onResume()
当你点击返回按钮或尝试调用finish()方法来结束活动时,事件会按照以下方式被调用:
onPause()
onStop()
onDestroy()
Android操作系统使用优先级队列来协助管理设备上运行的活动。基于特定Android活动所处的状态,它将在操作系统内被分配一定的优先级。这种优先级系统有助于Android识别不再使用的活动,从而允许操作系统回收内存和资源。以下图表说明了活动在其生命周期中可以经历的状态:
这些状态可以分为三组,如下所示:
激活或运行 - 如果活动位于前台,也就是活动堆栈的顶部,则认为活动是激活或正在运行的。这被认为是Android活动堆栈中最高优先级的活动,因此只有在极端情况下,例如如果活动尝试使用多于设备可用内存的内存,可能会导致用户界面无响应等情况时,操作系统才会强制结束该活动。
暂停 - 当设备进入睡眠状态,或者一个活动仍然可见但被新的非全屏或透明活动部分遮挡时,该活动被认为是暂停的。暂停的活动仍然存活,也就是说,它们保持所有状态和成员信息,并继续附加到窗口管理器。这被认为是Android活动堆栈中第二高优先级的活动,因此,只有在结束此活动将满足维持激活/运行活动稳定和响应所需的资源要求时,操作系统才会强制结束该活动。
停止 - 完全被其他活动遮挡的活动被认为是已停止或处于后台。已停止的活动仍然尝试保留其状态和成员信息,但已停止的活动被认为是三种状态中优先级最低的,因此,操作系统首先会结束该状态下的活动以满足更高优先级活动的资源需求。
*样本活动以了解生命周期*
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends Activity {
String tag = "LifeCycleEvents";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Log.d(tag, "In the onCreate() event");
}
public void onStart()
{
super.onStart();
Log.d(tag, "In the onStart() event");
}
public void onRestart()
{
super.onRestart();
Log.d(tag, "In the onRestart() event");
}
public void onResume()
{
super.onResume();
Log.d(tag, "In the onResume() event");
}
public void onPause()
{
super.onPause();
Log.d(tag, "In the onPause() event");
}
public void onStop()
{
super.onStop();
Log.d(tag, "In the onStop() event");
}
public void onDestroy()
{
super.onDestroy();
Log.d(tag, "In the onDestroy() event");
}
}
Activity 有六个状态
Activity 生命周期 有七种方法
onCreate()
onStart()
onResume()
onPause()
onStop()
onRestart()
onDestroy()
情况
打开应用程序时
onCreate() --> onStart() --> onResume()
当按下返回按钮并退出应用程序时
onPaused() -- > onStop() --> onDestory()
当按下主页按钮时
onPaused() --> onStop()
当用户按下主屏幕按钮后,再从最近任务列表中打开应用程序或点击图标时
onRestart() --> onStart() --> onResume()
当从通知栏打开应用程序或打开设置时
onPaused() --> onStop()
从其他应用程序或设置按下返回按钮后,可以看到我们的应用程序
onRestart() --> onStart() --> onResume()
当屏幕上打开任何对话框时
onPause()
关闭对话框或从对话框返回后
onResume()
任何手机都在响铃,用户正在应用程序中
onPause() --> onResume()
当用户按下手机的接听按钮时
onPause()
通话结束后
onResume()
当手机屏幕关闭时
onPaused() --> onStop()
当屏幕重新点亮时
onRestart() --> onStart() --> onResume()
onCreateAndPrepareToDisplay() [instead of onCreate() ]
onPrepareToDisplay() [instead of onRestart() ]
onVisible() [instead of onStart() ]
onBeginInteraction() [instead of onResume() ]
onPauseInteraction() [instead of onPause() ]
onInvisible() [instead of onStop]
onDestroy() [no change]
活动图可以解释为:
安卓应用程序的生命周期由七种方法管理:
让我们来看一个简单的场景,了解这些方法的调用顺序将帮助我们清楚地知道它们为什么被使用。
onCreate()
- - - > onStart()
- - - > onResume()
onPause()
- - - > onStop()
onRestart()
- - - > onStart()
- - - > onResume()
onStop()
- - - > onDestroy()
启动状态包括:
创建一个新的Linux进程,为新的UI对象分配新的内存,并设置整个屏幕。因此,大部分工作都在这里完成。
运行状态包括:
它是当前显示在屏幕上的活动(状态)。这种状态单独处理屏幕上的输入、触摸和点击按钮等事项。
暂停状态包括:
当一个活动不在前台,而是在后台时,该活动被称为处于暂停状态。
停止状态包括:
只能通过重新启动来将停止的活动带入前台,并且可以在任何时候销毁它。
活动管理器以这样的方式处理所有这些状态,以便用户体验和性能始终达到最佳状态,即使在将新活动添加到现有活动的情况下也是如此。
来自Android开发者页面,
onPause():
当系统即将开始恢复先前的活动时调用。 这通常用于提交未保存的更改到持久数据、停止动画和其他可能占用CPU等资源的操作。 此方法的实现必须非常快,因为下一个活动只有在此方法返回后才会恢复。 然后是onResume(),如果活动返回到前台,则后面是onStop(),如果它变得对用户不可见。
onStop():
当活动对用户不再可见时调用,因为另一个活动已经被恢复并覆盖了这个活动。 这可能是因为正在启动新的活动,正在将现有的活动带到这个活动的前面,或者正在销毁这个活动。 如果此活动要与用户交互,则后面跟着onRestart(),否则后面跟着onDestroy()。
现在假设有三个活动,您从A转到B,那么A的onPause将被调用,现在从B到C,然后B的onPause和A的onStop将被调用。
暂停的活动将获得恢复,而停止的活动将重新启动。
当您调用this.finish()
时,将调用onPause-onStop-onDestroy。需要记住的主要事项是:暂停的活动会被停止,而停止的活动会在Android需要内存进行其他操作时被销毁。
希望这足够清晰。
Create - Activity is created.
Start - Current activity gets started.
Resume - Current activity has been in resumed state.
Restart - Current activity has been in restarted.
Pause - Current activity has been in Paused state.
Stop - Current activity has been in stopped state.
destroy - Current activity has been in destroyed state.
onCreate()
onStart()
onResume()
当你从Android Studio运行应用程序时:
onCreate()
onStart()
onResume()
活动转换:
当从第一个活动移动到第二个活动时:
first_activity : onPause()
second_activity : onCreate()
second_activity : onStart()
second_activity : onResume()
first_activity : onStop()
从第二个活动切换到第一个活动:
second_activity : onPause()
first_activity : onRestart()
first_activity : onStart()
first_activity : onResume()
second_activity : onStop()
second_activity : onDestroy()
概览按钮:
当用户点击概览按钮(硬件第三个按钮 - 最近使用列表)时:
onPause()
onStop()
onRestart()
onStart()
onResume()
主页按钮:
当用户点击主页按钮时:
onPause()
onStop()
用户在主屏幕上搜索并点击应用程序图标返回到活动界面:
onRestart()
onStart()
onResume()
用户接到电话:
当用户在一个Activity中时,会接到电话:
onPause()
onStop()
如果用户不接听电话,则电话会自动断开并返回到活动页面(未接来电):
onRestart()
onStart()
onResume()
如果用户未接听电话:
无 - 不会调用任何生命周期。
关机按钮:
当用户关闭电源按钮时:
onPause()
onStop()
当解锁设备时:
onRestart()
onStart()
onResume()
弹出对话框:
当弹出对话框出现时,不会调用任何生命周期函数。
重新启动设备或关闭:
当用户重新启动或关闭设备时:
onPause()
onStop()
onCreate()
onStart()
onResume()
在高评分答案的基础上添加更多信息(添加了KILLABLE的附加部分和下一组将在生命周期中调用的方法):
请注意上表中的"Killable"列。对于那些被标记为可杀死的方法,在该方法返回后,托管活动的进程可能随时被系统杀死,而不执行其代码的另一行。
因此,您应该使用onPause()
方法将任何持久性数据(例如用户编辑)写入存储。此外,方法onSaveInstanceState(Bundle)
会在将活动放置在这种后台状态之前调用,允许您将活动中的任何动态实例状态保存到给定的Bundle
中,以便稍后在onCreate(Bundle)
中接收,如果需要重新创建活动。
请注意,将持久数据保存在onPause()
中比在onSaveInstanceState(Bundle)
中进行重要,因为后者不是生命周期回调的一部分,因此不会在其文档中描述的每种情况下都被调用。
我想再添加几个方法。这些没有列为生命周期方法,但根据某些条件在生命周期期间将被调用。根据您的要求,您可能必须在您的应用程序中实现这些方法,以正确处理状态。
onPostCreate(Bundle savedInstanceState)
onStart()
和onRestoreInstanceState(Bundle)
方法调用完成后,活动启动完成时调用该方法。onPostResume()
onResume()
方法被调用后,当活动恢复完成时调用。onSaveInstanceState(Bundle outState)
onCreate(Bundle)
或onRestoreInstanceState(Bundle)
中恢复状态(由此方法填充的Bundle将传递给两者)。请保留HTML标记。onRestoreInstanceState(Bundle savedInstanceState)
当活动从先前保存的状态重新初始化时,此方法在
onStart()
之后调用,并在此处使用savedInstanceState
。
我的应用程序代码使用所有这些方法:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private EditText txtUserName;
private EditText txtPassword;
Button loginButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d("Ravi","Main OnCreate");
txtUserName=(EditText) findViewById(R.id.username);
txtPassword=(EditText) findViewById(R.id.password);
loginButton = (Button) findViewById(R.id.login);
loginButton.setOnClickListener(this);
}
@Override
public void onClick(View view) {
Log.d("Ravi", "Login processing initiated");
Intent intent = new Intent(this,LoginActivity.class);
Bundle bundle = new Bundle();
bundle.putString("userName",txtUserName.getText().toString());
bundle.putString("password",txtPassword.getText().toString());
intent.putExtras(bundle);
startActivityForResult(intent,1);
// IntentFilter
}
public void onActivityResult(int requestCode, int resultCode, Intent resIntent){
Log.d("Ravi back result:", "start");
String result = resIntent.getStringExtra("result");
Log.d("Ravi back result:", result);
TextView txtView = (TextView)findViewById(R.id.txtView);
txtView.setText(result);
Intent sendIntent = new Intent();
//sendIntent.setPackage("com.whatsapp");
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "Message...");
sendIntent.setType("text/plain");
startActivity(sendIntent);
}
@Override
protected void onStart() {
super.onStart();
Log.d("Ravi","Main Start");
}
@Override
protected void onRestart() {
super.onRestart();
Log.d("Ravi","Main ReStart");
}
@Override
protected void onPause() {
super.onPause();
Log.d("Ravi","Main Pause");
}
@Override
protected void onResume() {
super.onResume();
Log.d("Ravi","Main Resume");
}
@Override
protected void onStop() {
super.onStop();
Log.d("Ravi","Main Stop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d("Ravi","Main OnDestroy");
}
@Override
public void onPostCreate(Bundle savedInstanceState, PersistableBundle persistentState) {
super.onPostCreate(savedInstanceState, persistentState);
Log.d("Ravi","Main onPostCreate");
}
@Override
protected void onPostResume() {
super.onPostResume();
Log.d("Ravi","Main PostResume");
}
@Override
public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
super.onSaveInstanceState(outState, outPersistentState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
}
登陆活动:
public class LoginActivity extends AppCompatActivity {
private TextView txtView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
txtView = (TextView) findViewById(R.id.Result);
Log.d("Ravi","Login OnCreate");
Bundle bundle = getIntent().getExtras();
txtView.setText(bundle.getString("userName")+":"+bundle.getString("password"));
//Intent intent = new Intent(this,MainActivity.class);
Intent intent = new Intent();
intent.putExtra("result","Success");
setResult(1,intent);
// finish();
}
}
输出:(暂停之前)
D/Ravi: Main OnCreate
D/Ravi: Main Start
D/Ravi: Main Resume
D/Ravi: Main PostResume
输出:(从暂停恢复后)
D/Ravi: Main ReStart
D/Ravi: Main Start
D/Ravi: Main Resume
D/Ravi: Main PostResume
onPostResume()
仍会被调用。开始活动
On Activity Load (First Time)
————————————————————————————————————————————————
D/IndividualChatActivity: onCreate:
D/IndividualChatActivity: onStart:
D/IndividualChatActivity: onResume:
D/IndividualChatActivity: onPostResume:
Reload After BackPressed
————————————————————————————————————————————————
D/IndividualChatActivity: onCreate:
D/IndividualChatActivity: onStart:
D/IndividualChatActivity: onResume:
D/IndividualChatActivity: onPostResume:
OnMaximize(Circle Button)
————————————————————————————————————————————————
D/IndividualChatActivity: onRestart:
D/IndividualChatActivity: onStart:
D/IndividualChatActivity: onResume:
D/IndividualChatActivity: onPostResume:
OnMaximize(Square Button)
————————————————————————————————————————————————
D/IndividualChatActivity: onRestart:
D/IndividualChatActivity: onStart:
D/IndividualChatActivity: onResume:
D/IndividualChatActivity: onPostResume:
停止活动
On BackPressed
————————————————————————————————————————————————
D/IndividualChatActivity: onPause:
D/IndividualChatActivity: onStop:
D/IndividualChatActivity: onDestroy:
OnMinimize (Circle Button)
————————————————————————————————————————————————
D/IndividualChatActivity: onPause:
D/IndividualChatActivity: onStop:
OnMinimize (Square Button)
————————————————————————————————————————————————
D/IndividualChatActivity: onPause:
D/IndividualChatActivity: onStop:
Going To Another Activity
————————————————————————————————————————————————
D/IndividualChatActivity: onPause:
D/IndividualChatActivity: onStop:
Close The App
————————————————————————————————————————————————
D/IndividualChatActivity: onDestroy:
在我个人看来,只有onStart和onStop是必需的。
每次返回都似乎需要onResume,而每次离开(除了关闭应用程序)都需要onPause。