Android活动的生命周期是什么?为什么这么多的发音相似的方法(onCreate()
,onStart()
,onResume()
)初始化过程中调用,和许多其他人(onPause()
,onStop()
,onDestroy()
)呼吁在结束了吗?
这些方法何时调用,应如何正确使用?
Android活动的生命周期是什么?为什么这么多的发音相似的方法(onCreate()
,onStart()
,onResume()
)初始化过程中调用,和许多其他人(onPause()
,onStop()
,onDestroy()
)呼吁在结束了吗?
这些方法何时调用,应如何正确使用?
Answers:
在Activity Lifecycle中查看(在Android Developers中)。
在第一次创建活动时调用。这是您应进行所有常规静态设置的地方:创建视图,将数据绑定到列表等。此方法还为您提供了一个包含活动先前冻结状态(如果存在)的捆绑包。始终跟在onStart()之后。
在您的活动停止之后,再次开始之前调用。始终跟随onStart()
当活动对用户可见时调用。如果活动进入前台,则紧跟着onResume()。
当活动将开始与用户互动时调用。此时,您的活动位于活动堆栈的顶部,而用户输入将进入该活动堆栈。始终跟随onPause()。
当活动进入后台但尚未被杀死时,被称为活动生命周期的一部分。与onResume()对应。当活动B在活动A之前启动时,将在A上调用此回调。在A的onPause()返回之前,将不会创建B。因此,请确保此处不要做任何冗长的操作。
当您不再对用户可见时调用。接下来,您将收到onRestart(),onDestroy()或什么都不接收,这取决于以后的用户活动。请注意,在内存不足的情况下,如果系统的内存不足,无法在调用onPause()方法后保持活动的进程运行,则永远不要调用此方法。
活动销毁之前收到的最后一个电话。这可能是由于活动即将完成(有人在其上称为finish(),或者是因为系统正在临时销毁该活动实例以节省空间)。您可以使用isFinishing()方法区分这两种情况。
当Activity 第一次加载时,将按以下方式调用事件:
onCreate()
onStart()
onResume()
当您单击“电话”按钮时,活动进入后台,并调用以下事件:
onPause()
onStop()
退出电话拨号程序,将调用以下事件:
onRestart()
onStart()
onResume()
当您单击后退按钮或尝试完成()活动时,将按以下方式调用事件:
onPause()
onStop()
onDestroy()
Android操作系统使用优先级队列来协助管理设备上运行的活动。根据特定Android活动所处的状态,系统将在OS中为其分配特定的优先级。此优先级系统可帮助Android识别不再使用的活动,从而允许OS回收内存和资源。下图说明了活动在其生命周期内可以通过的状态:
这些状态可以分为以下三个主要组:
活动或正在运行 -如果活动位于前台(也称为活动堆栈的顶部),则被视为活动或正在运行。这被认为是Android Activity堆栈中最高优先级的活动,因此只有在极端情况下,OS才会将其杀死,例如,如果该活动尝试使用的设备内存超过设备上的可用内存,因为这可能导致UI变得反应迟钝。
已暂停 -设备进入睡眠状态,或者某个活动仍然可见但被新的非标准尺寸或透明活动部分隐藏时,该活动被视为已暂停。暂停的活动仍然有效,也就是说,它们保留了所有状态和成员信息,并仍附加到窗口管理器。这被认为是Android Activity堆栈中第二高优先级的活动,因此,只有在杀死该活动满足保持Active / Running活动稳定和响应所需的资源要求的情况下,OS才会将其终止。
已停止 -被其他活动完全遮盖的活动被视为已停止或处于后台。停止的活动仍会尝试尽可能长时间地保留其状态和成员信息,但是停止的活动被认为是这三个状态中的最低优先级,因此,操作系统将首先杀死处于该状态的活动以满足资源需求。高优先级的活动。
*样本活动以了解生命周期**
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");
}
}
活动有六个州
活动生命周期有七种方法
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()
造成整个混乱的原因是Google选择了非直观的名称,而不是如下所示的名称:
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]
活动图可以解释为:
有七种方法可以管理Android应用程序的生命周期:
让我们以一个简单的场景为例,在这些场景中,知道这些方法的调用顺序将有助于我们弄清楚为什么要使用它们。
onCreate()
---> ---->onStart()
onResume()
onPause()
---> onStop()
onRestart()
---> ---->onStart()
onResume()
onStop()
---> onDestroy()
起始状态包括:
创建一个新的Linux进程,为新的UI对象分配新的内存,并设置整个屏幕。因此,大部分工作都在这里进行。
运行状态包括:
屏幕上当前是活动(状态)。仅此状态就处理诸如在屏幕上键入以及触摸和单击按钮之类的事情。
暂停状态包括:
当某个活动不在前台而在后台时,则称该活动处于暂停状态。
停止状态涉及:
停止的活动只能通过重新启动进入前台,也可以随时将其销毁。
活动管理器以这样的方式处理所有这些状态:即使在将新活动添加到现有活动的情况下,用户体验和性能也始终处于最佳状态
我喜欢这个问题及其答案,但是到目前为止,还没有覆盖不那么常用的回调,例如onPostCreate()或onPostResume()。史蒂夫·波默罗伊(Steve Pomeroy)在https://github.com/xxv/android-lifecycle上尝试了包括这些内容以及它们与Android Fragment生命周期的关系的图表。我修改了Steve的大图,使其仅包含“ 活动”部分,并对其进行了格式化,以使其达到字母大小的一页打印输出。我将其以文本PDF格式发布在https://github.com/code-read/android-lifecycle/blob/master/AndroidActivityLifecycle1.pdf,以下是其图像:
在“ Android开发者”页面上,
onPause():
在系统将要开始恢复上一个活动时调用。此方法通常用于对持久性数据提交未保存的更改,停止动画以及可能消耗CPU的其他操作,等等。此方法的实现必须非常快,因为在此方法返回之前,下一个活动将不会恢复。如果活动返回到最前面,则紧随其后的是onResume(),如果用户看不到该活动,则紧随其后的是onStop()。
onStop():
当活动不再对用户可见时调用,因为另一个活动已经恢复并且正在覆盖该活动。这可能是由于新活动正在启动,现有活动被带到该活动的前面或该活动被销毁而发生的。如果此活动返回与用户交互,则紧跟其后的是onRestart(),或者如果此活动消失,则紧跟其后的是onDestroy()。
现在假设有三个活动,您从A转到B,然后现在将A的onPause从B调用到C,然后将调用B的onPause和A的onStop。
暂停的活动将恢复,停止的活动将重新启动。
当您调用时this.finish()
,将调用onPause-onStop-onDestroy。要记住的主要事情是:每当Android需要内存进行其他操作时,暂停的活动就会停止,并且已终止的活动会被销毁。
我希望它足够清楚。
在评分很高的答案的基础上添加更多信息(添加了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将传递给这两个方法)。
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在每个离开的实例中(关闭应用程序除外)。