activity生命周期,启动模式详解

Activity五个状态

Starting(启动状态)->running(运行状态)->paused(暂停状态)->Stopped(停止状态)->Destroyed(销毁状态)
关于activity四个状态的生命周期:
请添加图片描述

  • 启动状态(Starting):Activity的启动状态很短暂,当Activity启动后便会进入运行状态(Running)。
  • 运行状态(Running):Activity在此状态时处于屏幕最前端,它是可见、有焦点的,可以与用户进行交互。如单击、长按等事件。即使出现内存不足的情况,Android也会先销毁栈底的Activity,来确保当前的Activity正常运行。
  • 暂停状态(Paused):在某些情况下,Activity对用户来说仍然可见,但它无法获取焦点,用户对它操作没有没有响应,此时它处于暂停状态。例如,当前Activity弹出Dialog,或者新启动Activity为透明的Activity等情况。
  • 停止状态(Stopped):当Activity完全不可见时,它处于停止状态,但仍然保留着当前的状态和成员信息。如系统内存不足,那么这种状态下的Activity很容易被销毁。
  • 销毁状态(Destroyed):当Activity处于销毁状态时,将被清理出内存。

一些极端情况下,例如系统内存不足,也可能在Paused状态中,直接被系统杀死进入Kill。

Activity的生命周期

activity的生命周期
oncreate()->onstart()->onResume()->onRestart()->onPouse()->onStop()->onDestory()
在这里插入图片描述
上面图概括了android生命周期的各个环节,描述了activity从生成到销毁的过程。

  • onCreate() : 在Activity创建时调用,通常做一些初始化设置,不可以执行耗时操作。;

  • onNewIntent()*:注意 !!只有当 当前activity实例已经处于任务栈顶,并且使用启动模式为singleTop或者SingleTask再次启动Activity时才会调用此方法。此时不会走OnCreate(),而是会执行onNewIntent()。因为activity不需要创建而是直接复用。

  • onStart(): 在Activity即将可见时调用;可以做一些动画初始化的操作。

  • onRestoreInstanceState()*:注意 !!当app异常退出重建时才会调用此方法。可以在该方法中恢复以保存的数据

  • onResume(): 在Activity已可见,获取焦点开始与用户交互时调用;当Activity第一次启动完成或者当前Activity被遮挡住一部分(进入了onPause())重新回到前台时调用,比如弹窗消失。当onResume()方法执行完毕之后Activity就进入了运行状态。根据官方的建议,此时可以做开启动画和独占设备的操作。

  • onPause(): 在当前Activity被其他Activity覆盖或锁屏时调用;Activity停止但是当前Activity还是处于用户可见状态,比如出现弹窗;在onPause()方法中不能进行耗时操作(当前Activity通过Intent启动另一个Activity时,会先执行当前Activity的onPause()方法,再去执行另一个Activity的生命周期)

  • onSaveInstanceState():注意 !! 只有当app可能会异常销毁时才会调用此方法保存activity数据。以便于activity重建时恢复数据
    Activity的onSaveInstanceState回调时机,取决于app的targetSdkVersion:
    targetSdkVersion低于11的app,onSaveInstanceState方法会在Activity.onPause之前回调;
    targetSdkVersion低于28的app,则会在onStop之前回调;
    28之后,onSaveInstanceState在onStop回调之后才回调。

  • onStop() : 在Activity完全被遮挡对用户不可见时调用(在onStop()中做一些回收资源的操作)

  • onDestroy() :在Activity销毁时调用;

  • onRestart() : 在Activity从停止状态再次启动时调用;处于stop()状态也就是完全不可见的Activity重新回到前台时调用(重新回到前台不会调用onCreate()方法,因为此时Activity还未销毁)

Activity横竖屏切换生命周期

横竖屏切换涉及到的是Activity的android:configChanges属性;
android:configChanges可以设置的属性值有:

  • orientation:消除横竖屏的影响
  • keyboardHidden:消除键盘的影响
  • screenSize:消除屏幕大小的影响
public class MainActivity extends AppCompatActivity {
public static final String TAG=MainActivity;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.i(TAG,"onCreate");
    setContentView(R.layout.activity_main);
}

@Override
protected void onStart() {
    super.onStart();
    Log.i(TAG,"onStart");
}

@Override
protected void onResume() {
    super.onResume();
    Log.i(TAG,"onResume.........");
}

@Override
protected void onPause() {
    super.onPause();
    Log.i(TAG,"onPause");
}

@Override
protected void onStop() {
    super.onStop();
    Log.i(TAG,"onStop");
}

@Override
protected void onDestroy() {
    super.onDestroy();
    Log.i(TAG,"onDestroy");
}

启动activity,生命周期如下:
onCreate()->onStart()->onResume()
切换横屏,生命周期如下:
onPause()->onStop()->onSaveInstanceState()->onDestroy()->onCreate()->onStart()->onRestoreInstanceState()->onResume()
再切换为竖屏,生命周期如下:
onPause()->onStop()->onSaveInstanceState()->onDestroy()->onCreate()->onStart()->onRestoreInstanceState()->onResume()
修改AndroidManifest.xml,添加android:configChanges="orientation"并切换横屏,生命周期如下:
onPause()->onStop()->onSaveInstanceState()->onDestroy()->onCreate()->onStart()->onRestoreInstanceState()->onResume()
再切换竖屏,生命周期如下:
onPause()->onStop()->onSaveInstanceState()->onDestroy()->onCreate()->onStart()->onRestoreInstanceState()->onResume()
修改AndroidManifest.xml,属性改为android:configChanges=“orientation|keyboardHidden|screenSize”,切换横屏,生命周期如下:
onConfigurationChanged()
再切换回竖屏,生命周期如下:
onConfigurationChanged()

结论

设置Activity的android:configChanges属性为orientation或者orientation|keyboardHidden或者不设置这个属性的时候,横竖屏切换会重新调用各个生命周期方法,切横屏时会执行1次,切竖屏时会执行1次;
设置Activity的属性为android:configChanges="orientation|keyboardHidden|screenSize"时,横竖屏切换不会重新调用各个生命周期方法,只会执行onConfigurationChanged方法;

Activity的启动模式

一个项目中会包含多个activity,系统中使用任务栈来存储这些activity,任务栈呢,是一种“后进先出”的栈结构。举个栗子:当我们多次启动同一个(没有设置启动方式–即默认的启动方式)的activity的时候,系统会创建多个实例依次进入栈中。当back返回的时候,每按一次,一个activity出栈。直至栈空为止。
在这里插入图片描述

  • Standard 标准模式

无论任务栈内是否已经存在要启动的Activity实列,都会创建一个Activity放入任务栈,并置于栈顶。
使用场景:默认使用大多数场景

  • SingleTop栈顶复用模式

如果任务栈顶部已经存在一个要启动的Activity实列,就复用该Activity不会重新创建Activity的实列,复用Activity会执行onNewIntent方法,但是onCreate.onStart方法不会执行,因为它没有改变。如果任务栈顶没有实例就创建一个Activity实例存入其中,置于栈顶。

使用场景:适合接收通知内容显示页面,当用户从任务栏中进入查看消息内容界面时,如果设置为singleTop时,这样每次行为都使用同一个实例,用户点击返回时不会存在多个消息页面的情况。

  • SingleTask栈内复用模式

如果栈内已经存在要启动的Activity实例,就把该Activity栈上面的activity清出栈,让该activity置于栈顶,如果复用它的onNewIntent方法会被回调,但是onCreate方法不会执行,因为它没有改变.
使用场景:APP的首页,当你需要到某个页面时,关闭之前所打开的Activity可以用到。

SingleInstance单实例模式

这种模式启动的Activity实例单独占用一个任务栈,也就是启动该模式的Activity同时给它分配一个任务栈。

使用场景:singleInstance适合需要与程序分离开的页面。例如闹铃提醒,将闹铃提醒与闹铃设置分离。singleInstance不要用于中间页面,如果用于中间页面,跳转会有问题,比如:A -> B (singleInstance) -> C,完全退出后,在此启动,首先打开的是B。

Activity的数据保存与恢复

只有当Activity在异常状态下被结束时,系统才会调用onSaveInstanceState()方法,用于保存当前Activity的状态,以便后续在重建被异常结束的Activity时调用onSaveInstanceState()方法来恢复现场。

onSaveInstanceState()方法只在Activity被异常结束的时候调用,而且是在onStop之前。onSaveInstance方法会把数据保存在Bundle对象中,当被异常结束的Activity被重建以后,系统会调用onRestoreInstanceState方法,并把这个Bundle对象同时传递给onRestoreInstanceState和onCreate方法。因此onRestoreInstanceState方法可以用于恢复Activity的状态。onRestoreInstanceState方法的调用时机是在onStart之后。

那么,具体来说onSaveInstance方法会在什么时候被调用呢?

上面我也提到onSaveInstance方法是在onstop之前执行,也就是用户切换到桌面或者别的应用的时候就会被调用。onSaveInstance方法只在Activity被异常结束的时候调用,其实就是说当你的应用有可能被异常结束的时候,这个方法就会被调用。

下面这些都是应用有可能被异常结束的情况,这种时候系统就会调用onSaveInstance:

1、用户按home键切换到桌面

2、切换到别的应用

3、按下电源按钮/息屏

4、横竖屏切换

横竖屏切换的生命周期:onPause()->onSaveInstanceState()->onStop()->onDestroy()->onCreate()->onStart()->onRestoreInstanceState->onResume()

可以看出来横竖屏切换的时候经历了Activity的销毁和重建。如果我们不希望横竖屏导致Activity的销毁和重建,我们可以这样做:

在AndroidManifest文件的Activity中指定如下属性:

android:configChanges = "orientation| screenSize"

这样的话当应用进行横竖屏切换的时候,就不会经历Activity的销毁和重建了,而是回调以下方法:

@Override
public void onConfigurationChanged(Configuration newConfig){
    super.onConfigurationChanged(newConfig);
}

onRestoreInstatnceState()方法用于Activity被异常结束后再次创建的时候调用来恢复现场。但是需要注意的是,onRestoreInstanceState()方法不一定是和onSaveInstanceState()方法成对出现的。
onSaveInstanceState()方法是在系统判断Activity有可能被异常结束的时候就会被调用,而onRestoreInstanceState()方法则是必须要Activity真的被异常销毁之后并重建的时候才能调用。
比如用户先在Activity a中切换到Activity b,然后马上又返回到Activity a,因为从a切换到b的时候,系统判断为有可能会被异常销毁,所以会调用onSaveInstanceState()方法,但是因为Activity没有真正被销毁,所以从Activity b返回到Activity a的时候,Activity a不会调用onRestoreInstanceState()。onRestoreInstanceState()的调用基于Activity真的被异常销毁这个事实上。

另外,因为调用onSaveInstanceState()方法保存的Bundle对象会同时传递给onCreate()和onRestoreInstanceState()方法,所以也可以在onCreate()方法中进行恢复数据的操作。onCreate()和onRestoreInstanceState()方法恢复Activity的区别在于:

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    initView()
    BaseApplication.getApplication().startService(WebSocketConnectServer::class.java)
  }

  override fun onRestoreInstanceState(savedInstanceState: Bundle) {
    super.onRestoreInstanceState(savedInstanceState)
  }

  override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
  }

onRestoreInstanceState()回调则表明Bundle对象非空,不用加非空判断,而onCreate()中则需要非空判断,因此一般建议使用onRestoreInstanceState()方法来进行数据恢复。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在 Java 中,Activity 是 Android 应用程序的核心组件之一。它代表了用户与应用程序交互的一个屏幕,类似于 Windows 中的窗口。Activity 提供了一个用户界面,用于显示应用程序的内容,并处理用户输入。在本文中,我们将详细介绍 Java 中的 Activity。 1. Activity生命周期 Activity生命周期是指从创建到销毁的整个过程。Activity生命周期可以分为以下几个部分: 1.1. 创建阶段 在创建阶段,Activity 将完成以下几个步骤: 1.1.1. onCreate():当 Activity 被创建时,系统会调用 onCreate() 方法。在此方法中,开发者可以初始化 Activity 的布局、绑定事件等。 1.1.2. onStart():当 Activity 准备好与用户进行交互时,系统会调用 onStart() 方法。在此方法中,开发者可以完成一些初始化工作,例如开始动画。 1.1.3. onResume():当 Activity 成为用户焦点并可以与用户进行交互时,系统会调用 onResume() 方法。在此方法中,开发者可以开始处理用户输入事件。 1.2. 运行阶段 在运行阶段,Activity 将完成以下几个步骤: 1.2.1. onPause():当 Activity 失去焦点并不再与用户进行交互时,系统会调用 onPause() 方法。在此方法中,开发者可以停止处理用户输入事件。 1.2.2. onStop():当 Activity 不再可见时,系统会调用 onStop() 方法。在此方法中,开发者可以完成一些清理工作,例如停止动画。 1.3. 销毁阶段 在销毁阶段,Activity 将完成以下几个步骤: 1.3.1. onDestroy():当 Activity 被销毁时,系统会调用 onDestroy() 方法。在此方法中,开发者可以完成一些清理工作,例如释放资源。 2. Activity启动方式 在 Java 中,可以通过以下方式启动一个 Activity: 2.1. 显式启动 显式启动是指通过明确指定要启动Activity 的类名来启动 Activity。例如: ```java Intent intent = new Intent(this, AnotherActivity.class); startActivity(intent); ``` 2.2. 隐式启动 隐式启动是指通过指定 Action、Category、Data 等信息来启动 Activity,系统将根据这些信息匹配合适的 Activity。例如: ```java Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setData(Uri.parse("http://www.example.com")); startActivity(intent); ``` 3. Activity 的传值 在 Java 中,可以通过 Intent 对象来传递数据到另一个 Activity。具体步骤如下: 3.1. 在发送 Intent 时,通过 putExtra() 方法来添加数据: ```java Intent intent = new Intent(this, AnotherActivity.class); intent.putExtra("name", "张三"); intent.putExtra("age", 18); startActivity(intent); ``` 3.2. 在接收 Intent 时,通过 getIntent() 方法获取 Intent 对象,并通过 getXXXExtra() 方法获取数据: ```java Intent intent = getIntent(); String name = intent.getStringExtra("name"); int age = intent.getIntExtra("age", 0); ``` 4. Activity 的返回值 在 Java 中,可以通过 startActivityForResult() 方法启动一个 Activity,并在该 Activity 中设置 setResult() 方法来返回数据。具体步骤如下: 4.1. 在发送 Intent 时,通过 startActivityForResult() 方法启动另一个 Activity: ```java Intent intent = new Intent(this, AnotherActivity.class); startActivityForResult(intent, REQUEST_CODE); ``` 4.2. 在接收 Intent 时,通过 onActivityResult() 方法获取返回的数据: ```java @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) { String result = data.getStringExtra("result"); } } ``` 4.3. 在被返回的 Activity 中,通过 setResult() 方法设置返回的数据: ```java Intent intent = new Intent(); intent.putExtra("result", "返回数据"); setResult(RESULT_OK, intent); finish(); ``` 以上就是 Java 中 Activity详解,希望对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的code

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值