《第一行代码》读书笔记(二)

Author Avatar
wshunli 12月 06, 2017
  • 在其它设备中阅读本文章

《第一行代码》读书笔记 — 应用组件之 Activity

《第一行代码》读书笔记(一)— 平台架构 (第1章)
《第一行代码》读书笔记(二)— 应用组件之 Activity (第2、4章)
《第一行代码》读书笔记(三)— 应用组件之 Service (第10章)
《第一行代码》读书笔记(四)— 应用组件之 BroadcastReceiver (第5章)
《第一行代码》读书笔记(五)— 应用组件之 ContentProvider (第7章)
《第一行代码》读书笔记(六)— 数据存储方案 (第6章)
《第一行代码》读书笔记(七)— 多媒体资源 (第8章)
《第一行代码》读书笔记(八)— 网络编程 (第9章)

Android 应用的四大组件 Activity,Service,Broadcast Receiver, Content Provider 最为核心。

第2章 先从看得到的入手

Activity 是一个应用组件,用户可与其提供的屏幕进行交互,以执行拨打电话、拍摄照片或查看地图等操作。

Activity 创建、启动及销毁

要创建 Activity,必须创建 Activity 的子类(或使用其现有子类)。

实现用户界面

Activity 的用户界面是由层级式视图 — 衍生自 View 类的对象 — 提供的,也可以利用 Android 提供的现成视图设计和组织布局。

利用视图定义布局的最常见方法是借助保存在您的应用资源内的 XML 布局文件。

setContentView(R.layout.activity_main);

不过,也可以在 Activity 代码中创建新 View,并通过将新 View 插入 ViewGroup 来创建视图层次,然后通过将根 ViewGroup 传递到 setContentView() 来使用该布局。

声明 Activity

Activity 需要在 清单文件 中声明。

<manifest ... >
  <application ... >
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    ...
  </application ... >
  ...
</manifest >

<action> 元素指定这是应用的“主”入口点。
<category> 元素指定此 Activity 应列入系统的应用启动器内(以便用户启动该 Activity)。

启动 Activity

可以通过调用 startActivity(),并将其传递给描述想启动的 Activity 的 Intent 来启动另一个 Activity。

Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);

启动 Activity 推荐写法:

public class SecondActivity extends FirstActivity {
    public static void actionStart(Context context, String data1, String data2) {
        Intent intent = new Intent(context, SecondActivity.class);
        intent.putExtra("param1", data1);
        intent.putExtra("param2", data2);
        context.startActivity(intent);
    }
    ···
}

可以通过调用 startActivityForResult() 方法启动 Activity 并实现 onActivityResult() 回调方法得到启动 Activity 的结果。

private void pickContact() {
    Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
    startActivityForResult(intent, PICK_CONTACT_REQUEST);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // If the request went well (OK) and the request was PICK_CONTACT_REQUEST
    if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) {
        // Perform a query to the contact's content provider for the contact's name
        Cursor cursor = getContentResolver().query(data.getData(),
        new String[] {Contacts.DISPLAY_NAME}, null, null, null);
        if (cursor.moveToFirst()) { // True if the cursor is not empty
            int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);
            String name = cursor.getString(columnIndex);
            // Do something with the selected contact's name...
        }
    }
}

处理 Activity 结果时应该在 onActivityResult() 方法中使用的基本逻辑。

检查请求是否成功以及requestCode 与随 startActivityForResult() 发送的第二个参数是否匹配。
代码通过查询 Intent 中返回的数据(data 参数)从该处开始处理 Activity 结果。

结束 Activity

通过调用 Activity 的 finish() 方法来结束该 Activity。也可以通过调用 finishActivity() 结束之前启动的另一个 Activity。

Activity 生命周期

Activity 状态

Activity 在其生命周期中最多有4种状态:

  • 运行状态:Activity 位于屏幕前台并具有用户焦点。
  • 暂停状态:另一个 Activity 位于屏幕前台并具有用户焦点,但此 Activity 仍可见。
  • 停止状态:该 Activity 被另一个 Activity 完全遮盖(该 Activity 目前位于“后台”)。
  • 销毁状态:系统结束 Activity (调用其 finish() 方法)或直接终止其进程,将其从内存中删除。

生命周期回调

当一个 Activity 转入和转出上述不同状态时,系统会通过各种回调方法向其发出通知。

public class ExampleActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // The activity is being created.
    }
    @Override
    protected void onStart() {
        super.onStart();
        // The activity is about to become visible.
    }
    @Override
    protected void onResume() {
        super.onResume();
        // The activity has become visible (it is now "resumed").
    }
    @Override
    protected void onPause() {
        super.onPause();
        // Another activity is taking focus (this activity is about to be "paused").
    }
    @Override
    protected void onStop() {
        super.onStop();
        // The activity is no longer visible (it is now "stopped")
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        // The activity is about to be destroyed.
    }
}

这些方法共同定义 Activity 的整个生命周期。可以通过实现这些方法监控 Activity 生命周期中的三个嵌套循环:

  • 完整生命周期 发生在 onCreate() 与 onDestroy() 之间,就是完整的生存期。
  • 可见生命周期 发生在 onStart() 与 onStop() 之间。在这段时间,用户可以在屏幕上看到 Activity 并与其交互。
  • 前台生命周期 发生在 onResume() 与 onPause() 之间。在这段时间,Activity 位于屏幕上的所有其他 Activity 之前,并具有用户输入焦点。
![activity_lifecycle](https://img.wshunli.com/Android/第一行代码/2.activity_lifecycle.png)

Activity 生命周期回调方法汇总表。

activity_lifecycle

名为“是否能事后终止?”的列表示系统是否能在不执行另一行 Activity 代码的情况下,在方法返回后随时终止承载 Activity 的进程。

保存 Activity 状态

在 Activity 暂停或者停止时,Activity 的状态会得到保留。
但是当系统为了回复内存而销毁 Activity 时,Activity 对象也会被销毁,
我们可以使用 onSaveInstanceState() 方法保存 Acitivity 状态信息,使用 onRestoreInstanceState() 方法 恢复保存的状态信息。

![restore_instance](https://img.wshunli.com/Android/第一行代码/2.restore_instance.png)

当 Activity A 启动 Activity B 时一系列操作的发生顺序:

  1. Activity A 的 onPause() 方法执行。
  2. Activity B 的 onCreate()、onStart() 和 onResume() 方法依次执行。(Activity B 现在具有用户焦点。)
  3. 然后,如果 Activity A 在屏幕上不再可见,则其 onStop() 方法执行。

Intent 和 Intent 过滤器

Intent 是一个消息传递对象,可以使用它从其他应用组件请求操作。尽管 Intent 可以通过多种方式促进组件之间的通信,但其基本用例主要包括以下三个:

启动 Activity:Activity 表示应用中的一个屏幕。通过将 Intent 传递给 startActivity(),您可以启动新的 Activity 实例。Intent 描述了要启动的 Activity,并携带了任何必要的数据。

如果您希望在 Activity 完成后收到结果,请调用 startActivityForResult()。在 Activity 的 onActivityResult() 回调中,您的 Activity 将结果作为单独的 Intent 对象接收。

启动服务:Service 是一个不使用用户界面而在后台执行操作的组件。通过将 Intent 传递给 startService(),您可以启动服务执行一次性操作(例如,下载文件)。Intent 描述了要启动的服务,并携带了任何必要的数据。

如果服务旨在使用客户端-服务器接口,则通过将 Intent 传递给 bindService(),您可以从其他组件绑定到此服务。

传递广播:广播是任何应用均可接收的消息。系统将针对系统事件(例如:系统启动或设备开始充电时)传递各种广播。通过将 Intent 传递给 sendBroadcast()、sendOrderedBroadcast() 或 sendStickyBroadcast(),您可以将广播传递给其他应用。

显示Intent和隐式Intent

显式 Intent 按名称(完全限定类名)指定要启动的组件。

startActivity(new Intent(this, SecondActivity.class));

隐式 Intent 不会指定特定的组件,而是声明要执行的常规操作,从而允许其他应用中的组件来处理它。

创建隐式 Intent 时,Android 系统通过将 Intent 的内容与在设备上其他应用的清单文件中声明的 Intent 过滤器进行比较,从而找到要启动的相应组件。

intent-filters

隐式 Intent 如何通过系统传递以启动其他 Activity 的图解:
[1] Activity A 创建包含操作描述的 Intent,并将其传递给 startActivity()。
[2] Android 系统搜索所有应用中与 Intent 匹配的 Intent 过滤器。 找到匹配项之后,
[3] 该系统通过调用匹配 Activity(Activity B)的 onCreate() 方法并将其传递给 Intent,以此启动匹配 Activity。

构建 Intent

Intent 对象携带了 Android 系统用来确定要启动哪个组件的信息,以及收件人组件为了正确执行操作而使用的信息。

Intent 中包含的主要信息如下:

  • 组件名称(Component name):要启动的组件名称。
  • 操作(Action):指定要执行的通用操作的字符串。如 ACTION_VIEW 、ACTION_SEND。
  • 数据(Data):引用待操作数据和/或该数据 MIME 类型的 URI(Uri 对象)。
  • 类别(Category):一个包含应处理 Intent 组件类型的附加信息的字符串。如 CATEGORY_BROWSABLE、CATEGORY_LAUNCHER。
  • Extra:携带完成请求操作所需的附加信息的键值对。
  • 标志(Flags):在 Intent 类中定义的、充当 Intent 元数据的标志。

隐式创建 Intent 示例:

// Create the text message with a string
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
sendIntent.setType("text/plain");

// Verify that the intent will resolve to an activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(sendIntent);
}

使用应用选择器

如果有多个应用响应隐式 Intent,则用户可以选择要使用的应用,并将其设置为该操作的默认选项。

要显示选择器,请使用 createChooser() 创建 Intent,并将其传递给 startActivity()。

Intent sendIntent = new Intent(Intent.ACTION_SEND);
...
String title = getResources().getString(R.string.chooser_title);
// Create intent to show the chooser dialog
Intent chooser = Intent.createChooser(sendIntent, title);
if (sendIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(chooser);
}

接收隐式 Intent

要公布应用可以接收哪些隐式 Intent,需要在清单文件中使用 <intent-filter> 元素为每个应用组件声明一个或多个 Intent 过滤器。

<intent-filter> 内部,您可以使用以下三个元素中的一个或多个指定要接受的 Intent 类型:

<action> 在 name 属性中,声明接受的 Intent 操作。该值必须是操作的文本字符串值,而不是类常量。
<data> 使用一个或多个指定数据 URI 各个方面(scheme、host、port、path 等)和 MIME 类型的属性,声明接受的数据类型。
<category> 在 name 属性中,声明接受的 Intent 类别。该值必须是操作的文本字符串值,而不是类常量。

<activity android:name="ShareActivity">
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
</activity>

使用待定 Intent

PendingIntent 对象是 Intent 对象的包装器。PendingIntent 的主要目的是授权外部应用使用包含的 Intent,就像是它从您应用本身的进程中执行的一样。

待定 Intent 的主要用例包括:

  • 声明用户使用您的通知执行操作时所要执行的 Intent(Android 系统的 NotificationManager 执行 Intent)。
  • 声明用户使用您的 应用小部件执行操作时要执行的 Intent(主屏幕应用执行 Intent)。
  • 声明未来某一特定时间要执行的 Intent(Android 系统的 AlarmManager 执行 Intent)。

Intent 解析

当系统收到隐式 Intent 以启动 Activity 时,它根据以下三个方面将该 Intent 与 Intent 过滤器进行比较,搜索该 Intent 的最佳 Activity:

  • Intent 操作
<intent-filter>
    <action android:name="android.intent.action.EDIT" />
    <action android:name="android.intent.action.VIEW" />
    ...
</intent-filter>
  • Intent 数据(URI 和数据类型)
<intent-filter>
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    ...
</intent-filter>
  • Intent 类别
<intent-filter>
    <data android:mimeType="video/mpeg" android:scheme="http" ... />
    <data android:mimeType="audio/mpeg" android:scheme="http" ... />
    ...
</intent-filter>

Intent 匹配

通过 Intent 过滤器匹配 Intent,这不仅有助于发现要激活的目标组件,还有助于发现设备上组件集的相关信息。
例如,主页应用通过使用指定 ACTION_MAIN 操作和 CATEGORY_LAUNCHER 类别的 Intent 过滤器查找所有 Activity,以此填充应用启动器。

PackageManager 提供了一整套 query…() 方法来返回所有能够接受特定 Intent 的组件,resolve…() 方法来确定响应 Intent 的最佳组件。例如,queryIntentActivities()、queryIntentServices()、queryBroadcastReceivers()将返回能够执行那些作为参数传递的 Intent 的所有 组件 列表,但方法均不会激活组件,而只是列出能够响应的组件。

通用 Intent

主要是调用系统提供的一些服务,如闹钟、相机等等。

https://developer.android.com/guide/components/intents-common.html

Activity 启动模式

任务和返回栈

任务是指在执行特定作业时与用户交互的一系列 Activity。 这些 Activity 按照各自的打开顺序排列在堆栈(即返回栈)中。

diagram_backstack

当前 Activity 启动另一个 Activity 时,新 Activity 会被推到栈顶,并获得焦点。当用户按返回按钮时,当前 Activity 会从栈顶弹出并销毁。

当用户直接按 Home 键回到主屏幕时,尽管该任务中的所有 Activity 全部停止,但是任务的返回栈仍然不变。

即使来自其他任务,Activity 也可以多次实例化。

管理任务

通过使用 <activity> 清单文件元素中的属性

  • taskAffinity
  • launchMode
  • allowTaskReparenting
  • clearTaskOnLaunch
  • alwaysRetainTaskState
  • finishOnTaskLaunch

以及传递给 startActivity() 的 Intent 中的标志

  • FLAG_ACTIVITY_NEW_TASK
  • FLAG_ACTIVITY_CLEAR_TOP
  • FLAG_ACTIVITY_SINGLE_TOP

管理 Activity 如何与任务关联或者如何存在于返回栈中。

定义启动模式

使用清单文件

在清单文件中声明 Activity 时,您可以使用 <activity> 元素的 launchMode 属性指定 Activity 应该如何与任务关联。

launchMode 属性的启动模式共有四种:

“standard”(默认模式)每次启动 Activity 系统都会在任务中创建 Activity 的新实例并向其传送 Intent。Activity 可以多次实例化,而每个实例均可属于不同的任务,并且一个任务可以拥有多个实例。

“singleTop” 如果当前任务的顶部已存在 Activity 的一个实例,则系统会通过调用该实例的 onNewIntent() 方法向其传送 Intent,而不是创建 Activity 的新实例。Activity 可以多次实例化,而每个实例均可属于不同的任务,并且一个任务可以拥有多个实例(但前提是位于返回栈顶部的 Activity 并不是 Activity 的现有实例)。

“singleTask” 系统创建新任务并实例化位于新任务底部的 Activity。但是如果该 Activity 的一个实例已存在于一个单独的任务中,则系统会通过调用现有实例的 onNewIntent() 方法向其传送 Intent,而不是创建新实例。一次只能存在 Activity 的一个实例。

“singleInstance” 与 “singleTask” 相同,只是系统不会将任何其他 Activity 启动到包含实例的任务中。该 Activity 始终是其任务唯一仅有的成员;由此 Activity 启动的任何 Activity 均在单独的任务中打开。

使用 Intent 标志

启动 Activity 时,您可以通过在传递给 startActivity() 的 Intent 中加入相应的标志,修改 Activity 与其任务的默认关联方式。可用于修改默认行为的标志包括:

FLAG_ACTIVITY_NEW_TASK 在新任务中启动 Activity。如果已为正在启动的 Activity 运行任务,则该任务会转到前台并恢复其最后状态,同时 Activity 会在 onNewIntent() 中收到新 Intent。这会产生与 “singleTask” launchMode 值相同的行为。

FLAG_ACTIVITY_SINGLE_TOP 如果正在启动的 Activity 是当前 Activity(位于返回栈的顶部),则 现有实例会接收对 onNewIntent() 的调用,而不是创建 Activity 的新实例。这会产生与 “singleTop” launchMode 值相同的行为。

FLAG_ACTIVITY_CLEAR_TOP 如果正在启动的 Activity 已在当前任务中运行,则会销毁当前任务顶部的所有 Activity,并通过 onNewIntent() 将此 Intent 传递给 Activity 已恢复的实例(现在位于顶部),而不是启动该 Activity 的新实例。产生这种行为的 launchMode 属性没有值。

处理关联

“关联”指示 Activity 优先属于哪个任务。默认情况下,同一应用中的所有 Activity 彼此关联。

可以使用 <activity> 元素的 taskAffinity 属性修改任何给定 Activity 的关联。

taskAffinity 属性取字符串值,该值必须不同于在 <manifest> 元素中声明的默认软件包名称,因为系统使用该名称标识应用的默认任务关联。

在两种情况下,关联会起作用:

  • 启动 Activity 的 Intent 包含 FLAG_ACTIVITY_NEW_TASK 标志。
  • Activity 将其 allowTaskReparenting 属性设置为 “true”。

清理返回栈

如果用户长时间离开任务,则系统会清除所有 Activity 的任务,根 Activity 除外。
当用户再次返回到任务时,仅恢复根 Activity。

alwaysRetainTaskState 如果在任务的根 Activity 中将此属性设置为 “true”,则不会发生刚才所述的默认行为。即使在很长一段时间后,任务仍将所有 Activity 保留在其堆栈中。

clearTaskOnLaunch 如果在任务的根 Activity 中将此属性设置为 “true”,则每当用户离开任务然后返回时,系统都会将堆栈清除到只剩下根 Activity。 换而言之,它与 alwaysRetainTaskState 正好相反。 即使只离开任务片刻时间,用户也始终会返回到任务的初始状态。

finishOnTaskLaunch 此属性类似于 clearTaskOnLaunch,但它对单个 Activity 起作用,而非整个任务。 此外,它还有可能会导致任何 Activity 停止,包括根 Activity。 设置为 “true” 时,Activity 仍是任务的一部分,但是仅限于当前会话。如果用户离开然后返回任务,则任务将不复存在。

第4章 手机平板要兼容

Fragment 表示 Activity 中的行为或部分用户界面。Fragment 必须始终嵌入在 Activity 中,其生命周期直接受宿主 Activity 生命周期的影响。

fragments

创建 Fragment

要想创建 Fragment,必须创建 Fragment 的子类(或已有其子类)。

![fragment_lifecycle](https://img.wshunli.com/Android/第一行代码/2.fragment_lifecycle.png)

其他 Fragment 子类,DialogFragment、ListFragment、PreferenceFragment 。

构造 Fragment 界面

实现 onCreateView() 回调方法,Android 系统会在 Fragment 需要绘制其布局时调用该方法。

public static class ExampleFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.example_fragment, container, false);
    }
}

inflater 利用 XML 中定义的布局资源来拓展 Fragment 布局。

向 Activity 添加 Fragment

可以通过两种方式向 Activity 布局添加 Fragment :

在 Activity 的布局文件内声明 Fragment

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <fragment android:name="com.example.news.ArticleListFragment"
            android:id="@+id/list"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
    <fragment android:name="com.example.news.ArticleReaderFragment"
            android:id="@+id/viewer"
            android:layout_weight="2"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
</LinearLayout>

当系统创建此 Activity 布局时,会实例化在布局中指定的每个Fragment,并为每个Fragment调用 onCreateView() 方法,以检索每个Fragment的布局。系统会直接插入Fragment返回的 View 来替代 <fragment> 元素。

或者通过编程方式将 Fragment 添加到某个现有 ViewGroup:

用 FragmentTransaction 添加、移除或替换 Fragment 。

FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
// 使用 add() 方法添加一个 Fragment
ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();

添加没有 UI 的 Fragment :

使用 add(Fragment, String) 方法在 Activity 添加 Fragment,可以使用 Fragment 为 Activity 提供后台行为,而不显示额外 UI。

管理 Fragment

在 Activity 调用 getFragmentManager() 方法得到 FragmentManager 对象可以管理 Activity 中的 Fragment。

FragmentManager 执行的操作包括:

  • findFragmentById()(对于在 Activity 布局中提供 UI 的 Fragment )或 findFragmentByTag()(对于提供或不提供 UI 的 Fragment)获取 Activity 中存在的 Fragment。
  • popBackStack()(模拟用户发出的返回命令)将 Fragment 从返回栈中弹出。
  • addOnBackStackChangedListener() 注册一个侦听返回栈变化的侦听器。

执行 Fragment 事务

从 FragmentManager 获取 FragmentTransaction 实例,使用 add()、remove() 和 replace() 等方法动态管理 Fragment。

// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();

通过调用 addToBackStack() 可将替换事务保存到返回栈,以便用户能够通过按返回按钮撤消事务并回退到上一 Fragment 。

Fragment 与 Activity 通信

尽管 Fragment 是作为独立于 Activity 的对象实现,并且可在多个 Activity 内使用,但 Fragment 的特定实例会直接绑定到包含它的 Activity。

Fragment 可以通过 getActivity() 访问 Activity 实例,并轻松地执行在 Activity 布局中查找视图等任务。

View listView = getActivity().findViewById(R.id.list);

同样地,Activity 也可以使用 findFragmentById() 或 findFragmentByTag(),通过从 FragmentManager 获取对 Fragment 的引用来调用Fragment中的方法。例如:

ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);

处理 Fragment 生命周期

管理Fragment生命周期与管理 Activity 生命周期很相似。和 Activity 一样,Fragment也以三种状态存在:

Resumed Fragment在运行中的 Activity 中可见。
Paused 另一个 Activity 位于前台并具有焦点,但此Fragment所在的 Activity 仍然可见(前台 Activity 部分透明,或未覆盖整个屏幕)。
Stopped Fragment不可见。宿主 Activity 已停止,或Fragment已从 Activity 中移除,但已添加到返回栈。 停止Fragment仍然处于活动状态(系统会保留所有状态和成员信息)。不过,它对用户不再可见,如果 Activity 被终止,它也会被终止。

Activity 生命周期与 Fragment 生命周期之间的最显著差异在于它们在其各自返回栈中的存储方式。

默认情况下,Activity 停止时会被放入由系统管理的 Activity 返回栈;
不过,仅当您在移除 Fragment 的事务执行期间通过调用 addToBackStack() 显式请求保存实例时,系统才会将 Fragment 放入由宿主 Activity 管理的返回栈。

与 Activity 生命周期协调一致

Fragment所在的 Activity 的生命周期会直接影响Fragment的生命周期,其表现为,Activity 的每次生命周期回调都会引发每个Fragment的类似回调。
例如,当 Activity 收到 onPause() 时,Activity 中的每个Fragment也会收到 onPause()。

不过,Fragment 还有几个额外的生命周期回调:

  • onAttach() 在片段已与 Activity 关联时调用(Activity 传递到此方法内)。
  • onCreateView() 调用它可创建与片段关联的视图层次结构。
  • onActivityCreated() 在 Activity 的 onCreate() 方法已返回时调用。
  • onDestroyView() 在移除与片段关联的视图层次结构时调用。
  • onDetach() 在取消片段与 Activity 的关联时调用。
![activity_fragment_lifecycle](https://img.wshunli.com/Android/第一行代码/2.activity_fragment_lifecycle.png)

图示说明了受其宿主 Activity 影响的片段生命周期流。

参考资料
1、Activity | Android Developers
https://developer.android.com/guide/components/activities.html
2、Activity/Service 生命周期 · 笔试面试知识整理
https://hit-alibaba.github.io/interview/Android/basic/Activity-Service-Lifecircle.html
3、Intent 和 Intent 过滤器
https://developer.android.com/guide/components/intents-filters.html

如果本文对您有所帮助,且您手头还很宽裕,欢迎打赏赞助我,以支付网站服务器和域名费用。 https://paypal.me/wshunli 您的鼓励与支持是我更新的最大动力,我会铭记于心,倾于博客。
本文链接:https://www.wshunli.com/posts/b6bcc7db.html