Android笔试面试题AI答之Activity(2)

答案仅供参考,大部分为文心一言AI作答

1. 请介绍一下Activity 生命周期?

Activity 的生命周期是 Android 开发中一个非常核心的概念,它定义了 Activity 从创建到销毁的各个阶段。理解 Activity 的生命周期对于编写高效、稳定的 Android 应用至关重要。以下是 Activity 生命周期的详细介绍:

1. 完全生命周期

Activity 的完全生命周期从它被创建开始,到它被销毁结束。这个过程中,Activity 会经历以下关键阶段:

  • onCreate(Bundle savedInstanceState): 当 Activity 第一次被创建时调用。这是初始化 Activity 的好地方,比如设置布局文件、初始化成员变量等。savedInstanceState 参数包含了 Activity 之前的保存状态(如果有的话),通常用于在配置更改(如屏幕旋转)后恢复 Activity 的状态。

  • onStart(): 当 Activity 对用户可见时调用。此时 Activity 还没有位于前台,无法与用户交互。

  • onResume(): 当 Activity 可见且位于前台、开始与用户交互时调用。此时 Activity 处于运行状态。

  • onPause(): 当 Activity 被其他 Activity 覆盖或部分遮挡、即将失去焦点时调用。这是进行清理工作(如停止动画、停止播放音乐等)的好地方,但通常不会在这里保存持久化数据,因为 Activity 仍然可能会回到前台。

  • onStop(): 当 Activity 完全不可见时调用。如果 Activity 正在被销毁,或者另一个 Activity(无论是新的 Activity 还是之前存在的 Activity)完全覆盖了它,则会发生这种情况。

  • onDestroy(): 当 Activity 被销毁时调用。这是清理资源(如取消注册广播接收器、解绑服务等)的最后机会。

2. 可见生命周期

可见生命周期指的是 Activity 从对用户可见到完全不可见的阶段,包括 onStart()onResume()onPause()onStop() 方法。

  • onStart() 和 onStop(): 这两个方法标记了 Activity 是否对用户可见。

  • onResume() 和 onPause(): 这两个方法标记了 Activity 是否位于前台并可以与用户交互。

3. 前台生命周期

前台生命周期指的是 Activity 位于前台、用户可以与其交互的阶段,包括 onResume()onPause() 方法。这是 Activity 生命周期中最重要的一部分,因为大多数与用户的交互都发生在这个阶段。

4. 配置更改

当设备配置发生更改(如屏幕旋转)时,默认情况下,当前 Activity 会被销毁并重新创建,以匹配新的配置。但是,你可以通过重写 onSaveInstanceState(Bundle outState)onRestoreInstanceState(Bundle savedInstanceState) 方法来保存和恢复 Activity 的状态,从而避免在配置更改时丢失数据。

5. 特殊场景

  • onRestart(): 当 Activity 从停止状态重新启动时调用。这通常发生在用户返回到之前已停止的 Activity 时。

  • onNewIntent(Intent intent): 当 Activity 已经存在(即已经在任务栈中),并且用户再次通过某种方式(如通过 Intent 启动器)启动它时调用。此时,Activity 的 onCreate()onStart() 方法不会被调用,但会调用 onNewIntent() 方法,并将新的 Intent 作为参数传递给它。

了解 Activity 的生命周期对于编写能够正确响应各种用户操作和配置更改的 Android 应用至关重要。通过合理利用生命周期的各个阶段,你可以确保你的应用既高效又稳定。

2. 请介绍一下横竖屏切换时Activity的生命周期变化?

在Android中,当设备的屏幕方向(横屏与竖屏)发生变化时,默认情况下,当前Activity会被销毁并重新创建,以适应新的屏幕配置。这个过程中,Activity的生命周期会经历一系列的变化。不过,这个行为可以通过在AndroidManifest.xml中对Activity的android:configChanges属性进行设置来修改,从而避免Activity的重新创建。

1.默认行为(未设置android:configChanges

当屏幕方向变化时,Activity的生命周期变化如下:

  1. onPause():Activity即将失去焦点,但尚未完全停止。
  2. onSaveInstanceState(Bundle outState):在Activity即将被销毁之前调用,允许你保存Activity的当前状态。这个状态会在Activity重新创建时通过onCreate(Bundle savedInstanceState)onRestoreInstanceState(Bundle savedInstanceState)方法恢复。
  3. onStop():Activity不再可见。
  4. onDestroy():Activity正在被销毁。
  5. onCreate(Bundle savedInstanceState):Activity被重新创建。如果之前保存了状态,则savedInstanceState参数将包含之前的状态。
  6. onStart():Activity再次变得可见。
  7. onResume():Activity回到前台,准备与用户交互。

2.设置android:configChanges

如果你不想在屏幕方向变化时让Activity重新创建,可以在AndroidManifest.xml的<activity>标签中设置android:configChanges属性,包括orientation值。这样,当屏幕方向变化时,Activity将不会销毁并重新创建,而是会调用onConfigurationChanged(Configuration newConfig)方法。

例如:

<activity
    android:name=".MyActivity"
    android:configChanges="orientation|keyboardHidden|screenSize">
    ...
</activity>

注意:从Android 3.2(API级别13)开始,screenSize也必须包含在android:configChanges中,以确保在屏幕方向变化时Activity不会重新创建。

3.使用onConfigurationChanged(Configuration newConfig)

当设置了android:configChanges并包含orientation时,你需要重写onConfigurationChanged(Configuration newConfig)方法来处理屏幕方向变化。在这个方法中,你可以根据新的配置(如屏幕方向)来更新Activity的布局或资源。

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // 检查屏幕方向
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        // 现在是横屏
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        // 现在是竖屏
    }
    // 更新布局或资源
}

总之,屏幕方向变化时Activity的生命周期变化取决于你是否在AndroidManifest.xml中设置了android:configChanges属性。未设置时,Activity会经历销毁和重新创建的过程;设置了则只会调用onConfigurationChanged(Configuration newConfig)方法。

3. 两个Activity之间跳转时会执行的方法有哪些?

两个Activity之间跳转时,会涉及到一系列的方法调用,这些方法主要围绕Activity的生命周期和Intent的使用。以下是两个Activity之间跳转时可能会执行的主要方法:

1. 发起跳转的Activity(源Activity)

  • onPause():当Activity即将因为另一个Activity的启动而失去用户焦点时调用。此时,源Activity不再接受用户输入,但系统不会立即销毁它。
  • onSaveInstanceState(Bundle outState)(可选):在Activity即将被销毁之前调用,用于保存Activity的当前状态(如用户输入的数据)。这些数据会在Activity重新创建时通过onCreate(Bundle savedInstanceState)onRestoreInstanceState(Bundle savedInstanceState)方法恢复。然而,如果跳转是通过startActivityForResult()发起的,并且没有配置android:configChanges来避免Activity重新创建,那么这个方法在屏幕方向变化导致的Activity重建时也会被调用,但在此处的上下文中,它主要与Activity的保存和恢复状态相关。
  • startActivity(Intent intent)startActivityForResult(Intent intent, int requestCode):用于启动目标Activity。如果不需要从目标Activity接收结果,则使用startActivity(Intent intent);如果需要接收结果,则使用startActivityForResult(Intent intent, int requestCode),其中requestCode是一个请求码,用于在onActivityResult(int requestCode, int resultCode, Intent data)中识别是哪个请求返回了结果。

2. 目标Activity

  • onCreate(Bundle savedInstanceState):当Activity第一次被创建时调用。这是初始化Activity的好地方,比如设置布局文件、初始化成员变量等。如果Activity之前被销毁并保存了状态,则savedInstanceState参数会包含之前的状态,可以在这里恢复它。
  • onStart():当Activity变得可见时调用。
  • onResume():当Activity可见且位于前台、开始与用户交互时调用。此时Activity处于运行状态。

3. 当目标Activity需要返回数据给源Activity时

  • setResult(int resultCode, Intent data):在目标Activity中,使用此方法设置要返回给源Activity的数据和结果码。resultCode是一个整数值,用于标识操作的结果(如Activity.RESULT_OKActivity.RESULT_CANCELED),data是一个Intent对象,用于携带返回给源Activity的数据。
  • finish():在目标Activity中调用此方法以结束当前Activity,并将控制权返回给源Activity。如果源Activity是通过startActivityForResult()启动目标Activity的,则源Activity的onActivityResult(int requestCode, int resultCode, Intent data)方法将被调用,以接收从目标Activity返回的数据和结果码。

4. 源Activity接收返回数据

  • onActivityResult(int requestCode, int resultCode, Intent data):在源Activity中重写此方法以接收从目标Activity返回的数据和结果码。requestCode用于识别是哪个请求返回了结果,resultCode是目标Activity通过setResult()方法设置的结果码,data是包含返回数据的Intent对象。

需要注意的是,上述方法中的某些(如onSaveInstanceState)在正常情况下可能不会在简单的Activity跳转过程中被直接调用,除非涉及到Activity的重新创建(如屏幕方向变化或配置更改)。然而,在理解Activity之间跳转的过程中,了解这些方法的存在和它们的作用是很重要的。

4. 如何处理可能被系统回收的后台Activity?

处理可能被系统回收的后台Activity,并确保在被系统回收之前保存当前状态,是Android开发中常见的需求。这主要通过Activity的生命周期方法和onSaveInstanceState(Bundle outState)回调来实现。以下是一些关键步骤和最佳实践:

1. 理解Activity生命周期

首先,你需要深入理解Activity的生命周期,特别是与Activity被暂停、停止和销毁相关的回调方法。这些方法包括onPause()onStop()onDestroy()。然而,需要注意的是,onDestroy()方法并不总是会被调用,特别是在系统需要回收资源以释放内存时。

2. 使用onSaveInstanceState(Bundle outState)保存状态

当Activity即将被销毁(由于配置更改或系统需要回收内存)时,系统会调用onSaveInstanceState(Bundle outState)方法。这是保存Activity状态(如用户输入的数据、滚动位置等)的绝佳机会。你可以在这个方法中将需要保存的数据放入传入的Bundle对象中。

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    // 保存需要的数据
    outState.putString("key", "value");
    // 对于复杂的数据结构,可能需要使用序列化
    // outState.putSerializable("complexKey", complexObject);
}

3. 在onCreate(Bundle savedInstanceState)onRestoreInstanceState(Bundle savedInstanceState)中恢复状态

当Activity重新创建时(无论是由于配置更改还是系统恢复它),系统会调用onCreate(Bundle savedInstanceState)方法,并将之前保存的Bundle对象作为参数传递。你可以在这个方法中检查savedInstanceState是否为null,如果不为null,则从中恢复你的状态。

另外,你也可以选择覆盖onRestoreInstanceState(Bundle savedInstanceState)方法,它会在onStart()方法之后被调用,专门用于恢复之前保存的状态。但是,大多数情况下,在onCreate()中恢复状态就足够了。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (savedInstanceState != null) {
        // 恢复状态
        String value = savedInstanceState.getString("key");
        // 对于复杂的数据结构,进行反序列化
        // ComplexObject complexObject = (ComplexObject) savedInstanceState.getSerializable("complexKey");
    }
}

4. 处理配置更改

有时,Activity可能因为配置更改(如屏幕方向变化)而被销毁和重新创建。如果你不希望Activity因为这些更改而被销毁,可以在AndroidManifest.xml的<activity>标签中设置android:configChanges属性,并指定你想要处理的配置更改类型(如orientation|screenSize)。然后,在Activity中覆盖onConfigurationChanged(Configuration newConfig)方法来处理配置更改。

但是,请注意,滥用android:configChanges可能会导致应用难以适应新的设备配置和Android版本。因此,建议仅在你确信需要避免Activity重新创建时才使用它。

5. 使用ViewModel和LiveData(对于更复杂的状态管理)

如果你的应用使用MVVM架构,并且需要更复杂的状态管理,那么使用ViewModel和LiveData可能是一个更好的选择。ViewModel在配置更改和Activity重新创建时保持存活,因此它可以用来存储和恢复数据,而无需担心Activity的生命周期。

综上所述,通过合理利用Activity的生命周期方法、onSaveInstanceState()onRestoreInstanceState()回调,以及(可选地)ViewModel和LiveData,你可以有效地处理可能被系统回收的后台Activity,并在需要时恢复其状态。

相关推荐

  1. Android笔试面试AIActivity2

    2024-07-20 13:12:01       35 阅读
  2. Android笔试面试AIActivity(1)

    2024-07-20 13:12:01       25 阅读
  3. Android笔试面试AIActivity(3)

    2024-07-20 13:12:01       28 阅读
  4. Android笔试面试AI布局Layout(1)

    2024-07-20 13:12:01       33 阅读
  5. Android笔试面试AI控件Views(1)

    2024-07-20 13:12:01       24 阅读
  6. android 问题 --自问自

    2024-07-20 13:12:01       35 阅读
  7. 大数据面试Greenplum(2)

    2024-07-20 13:12:01       25 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-20 13:12:01       171 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-20 13:12:01       189 阅读
  3. 在Django里面运行非项目文件

    2024-07-20 13:12:01       157 阅读
  4. Python语言-面向对象

    2024-07-20 13:12:01       170 阅读

热门阅读

  1. HIVE:使用get_json_object解析json对象

    2024-07-20 13:12:01       37 阅读
  2. Elasticsearch索引管理和生命周期管理

    2024-07-20 13:12:01       35 阅读
  3. 现代生活背景下陶瓷艺术设计的延伸与发展

    2024-07-20 13:12:01       39 阅读
  4. LeetCode 2956.找到两个数组中的公共元素:哈希表

    2024-07-20 13:12:01       36 阅读
  5. 麦芒30全新绽放,中国电信勾勒出AI手机的新方向

    2024-07-20 13:12:01       42 阅读
  6. Prometheus 运维中实际的故障案例以及解决办法

    2024-07-20 13:12:01       32 阅读
  7. Gmsh应用程序编程接口

    2024-07-20 13:12:01       31 阅读
  8. 【Go系列】RPC和grpc

    2024-07-20 13:12:01       35 阅读
  9. Spark SQL----INSERT OVERWRITE DIRECTORY

    2024-07-20 13:12:01       36 阅读