如果 onAttach() 没有在片段代码中被重写怎么办?

2024-02-01

根据片段生命周期onAttach()之前被调用onCreate()以便它将托管活动分配给片段。所以,我想知道如果它不被覆盖会怎样。所有片段回调的默认定义是否已经存在?


来自文档 https://developer.android.com/reference/android/app/Fragment.html#onAttach(android.app.Activity):

void onAttach(活动活动)

一旦片段与其活动相关联,就会调用。此方法在 API 级别已被弃用 23. 使用 onAttach(Context) 代替。

如果重写此方法,则必须调用超类 执行。

void onAttach(上下文上下文)

当片段首次附加到其上下文时调用。 onCreate(Bundle) 将在此之后调用。

这是片段的生命周期设计。当您不重写该方法时,没有什么问题。

所有片段回调的默认定义是否已经存在?

不,您需要自己创建片段回调。onAttach()方法通常被重写以确保片段的父活动正在实现片段回调。像这样的东西(阅读更多内容与其他片段通信 https://developer.android.com/guide/fragments/communicate):

public class HeadlinesFragment extends ListFragment {
    OnHeadlineSelectedListener mCallback;

    // Container Activity must implement this interface
    public interface OnHeadlineSelectedListener {
        public void onArticleSelected(int position);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            mCallback = (OnHeadlineSelectedListener) context;
        } catch (ClassCastException e) {
            throw new ClassCastException(context.toString()
                    + " must implement OnHeadlineSelectedListener");
        }
    }

    ...
}

当父 Activity 未执行时OnHeadlineSelectedListener,应用程序将崩溃并抛出must implement OnHeadlineSelectedListener。因此,它将防止您在代码中引入逻辑错误。


UPDATE

目的是什么onAttach()?

根据片段生命周期 onAttach() 在 onCreate() 之前调用 以便它将托管活动分配给片段。

这实际上意味着什么?

简单的答案:这是 Fragment 的生命周期,我们可以知道 Fragment 何时附加到其父 Activity。

更多细节:

从以下内容的源代码onAttach() https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/app/Fragment.java#L1563:

/**
 * Called when a fragment is first attached to its context.
 * {@link #onCreate(Bundle)} will be called after this.
 */
@CallSuper
public void onAttach(Context context) {
    mCalled = true;
    final Activity hostActivity = mHost == null ? null : mHost.getActivity();
    if (hostActivity != null) {
        mCalled = false;
        onAttach(hostActivity);
    }
}

/**
 * @deprecated Use {@link #onAttach(Context)} instead.
 */
@Deprecated
@CallSuper
public void onAttach(Activity activity) {
    mCalled = true;

}

除了有关我们之前问题的文档之外,我们什么也看不到mHost.

Fragment 的源代码位于https://github.com/android/platform_frameworks_base/blob/master/core/java/android/app/Fragment.java#L435 https://github.com/android/platform_frameworks_base/blob/master/core/java/android/app/Fragment.java#L435,我们可以知道mhost实际上是一个FragmentHostCallback:

// Activity this fragment is attached to.
FragmentHostCallback mHost;

但是如果我们扫描所有的源代码Fragment,我们将无法得到任何线索mhost已初始化。

从Fragment生命周期图中我们知道,生命周期是从fragment被添加的时候开始的:

我们以编程方式添加片段:

FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

ExampleFragment fragment = new ExampleFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();

检查FragmentManager源代码第1200到1229行 https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/app/FragmentManager.java#L1220从方法moveToState():

void moveToState(Fragment f, int newState, int transit, int transitionStyle,
            boolean keepActive) {
}

我们有以下代码:

f.mHost = mHost;
f.mParentFragment = mParent;
f.mFragmentManager = mParent != null
        ? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl();

// If we have a target fragment, push it along to at least CREATED
// so that this one can rely on it as an initialized dependency.
if (f.mTarget != null) {
    if (mActive.get(f.mTarget.mIndex) != f.mTarget) {
        throw new IllegalStateException("Fragment " + f
                + " declared target fragment " + f.mTarget
                + " that does not belong to this FragmentManager!");
    }
    if (f.mTarget.mState < Fragment.CREATED) {
        moveToState(f.mTarget, Fragment.CREATED, 0, 0, true);
    }
}

dispatchOnFragmentPreAttached(f, mHost.getContext(), false);
f.mCalled = false;
f.onAttach(mHost.getContext());
if (!f.mCalled) {
    throw new SuperNotCalledException("Fragment " + f
            + " did not call through to super.onAttach()");
}
if (f.mParentFragment == null) {
    mHost.onAttachFragment(f);
} else {
    f.mParentFragment.onAttachFragment(f);
}

现在我们知道了mHost and onAttach()Fragment 的初始化和调用由FragmentManager.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如果 onAttach() 没有在片段代码中被重写怎么办? 的相关文章

  • 通过代码在创建时突出显示 ListView 项目

    我想在创建 listView 时突出显示 ListView 的第一行 0 我尝试了不同的方法 就像您在注释代码中看到的那样 但没有任何效果 这很奇怪 因为 OnItemClickListener 中的突出显示工作正常 它通过 xml 选择器
  • 虚拟回调接口

    在 Eclipse 为您创建的来自 Google 的示例主从流代码中 片段中包含以下内容 private Callbacks mCallbacks sDummyCallbacks public interface Callbacks pub
  • 无法在 Android Studio 中导出签名的 APK

    当我使用keytool list keystore path to keyfile jks并提供我的密码 我可以看到那里的条目 但是当我在尝试使用相同的密码生成签名的 APK 时使用相同的密码时 我收到错误 无法加载密钥库 密钥库被篡改 或
  • 嵌套 XML 布局文件

    android 有没有办法从另一个布局文件引用 xml 布局文件 为了更好地解释 我有一个名为layout1 xml 和layout2 xml 的布局文件 我可以从layout1 xml引用layout2 xml吗 用这个
  • relativelayout导致动画不起作用?

    我有一个活动 其布局仅包含一个 VideoView 这是 XML
  • VOIP通话录音

    我正在开发一个在 android 中录制 VOIP 通话的项目 我没有找到任何解决方案 有很多应用程序支持手机上的 VOIP 录音 我找不到任何教程和帮助 立方体通话记录器 https play google com store apps
  • 自动删除 Firebase 通知

    我有一个问题 我都读过让通知在 5 分钟后消失 https stackoverflow com questions 15648699 make notification disappear after 5 minutes and 几秒钟后清
  • 什么是 Android 测试协调器?

    谷歌最近发布了Android测试支持库1 0 读完后overview https android developers googleblog com 2017 07 android testing support library 10 is
  • 如何绘制部分位图圆弧?类似于圆形进度轮,但具有显示得越来越多的位图。

    我正在寻找的是一种以顺时针圆形方式显示图像的视图 当进度为 25 时 应显示前 90 度 当进度为 100 时 应绘制完整的 360 度 它与使用 canvas drawArc 非常接近 但此方法仅适用于 Paint 对象 不适用于位图 其
  • 在 Android 中加密/解密字符串的简单方法

    我的问题是如何加密String String AndroidId Override public void onCreate Bundle savedInstanceState super onCreate savedInstanceSta
  • 如何在同一设备上运行的 Android 应用程序之间传输文件?

    我正在编写一个与 RESTful 服务交互的 Android 应用程序 该 Web 服务本质上是一个文件系统 并提供元数据以及对文件的 CRUD 访问 我的应用程序检索元数据 并通过ContentProvider 我需要添加与我的应用程序在
  • 如何在Android模拟器中隐藏应用程序图标?

    我有一个应用程序在启动完成后自动启动 但应用程序图标显示在android模拟器中 现在我想向用户隐藏该图标 这样用户就无法知道应用程序已启动 并且他们无法启动该应用程序手动申请 在您的 AndroidManifest xml 文件中 您可能
  • 文本视图不显示全文

    我正在使用 TableLayout 和 TableRow 创建一个简单的布局 其中包含两个 TextView 这是代码的一部分
  • TextView.setMaxLines 不起作用?

    在我的应用程序中 我有一个屏幕 其中显示一些文本 然后显示一张照片 文本的长度是可变的 有时根本没有 有时很多 所以我想对其进行设置 以便文本永远不会占用超过几行 但可以滚动 为下面的图像留下足够的空间 我这部分的视图组件是以编程方式创建的
  • Android 中 Activity 之间的 3D 动画

    How to create animation between two Activity look like As Screen shot in android 搜索jazzyviewpager 这是link https github co
  • 通过 Gradle 和 Android Studio 构建和运行应用程序比通过 Eclipse 慢

    我有一个多项目 10 个模块 每次构建大约需要 20 30 秒 当我在 Android Studio 中按 运行 时 每次都必须等待才能重建应用程序 这非常慢 是否可以在 Android Studio 中自动化构建过程 或者您对如何加快此过
  • 动态更改按钮上的图像视图

    在我的应用程序中 我有按钮和ImageView 当我按下按钮时我想改变ImageView 我的可绘制文件夹中有 5 张图像 按下按钮时 ImageView 根据按钮单击一张一张地更改图像 我想要它的解决方案 感谢任何可以提供帮助的人 维护一
  • Android:透明活动问题

    最近 在我们的一款生产应用程序上 透明活动已停止工作 我的意思是它变成了黑色背景而不是透明背景 当我将活动的背景颜色设置为纯色 即红色 绿色等 时 它的应用不会出现问题 该问题可能是由于迁移到 AndroidX 引起的 但我没有这方面的证据
  • 如何正确处理 ListView 内的 Android EditText 输入?

    在我的应用程序中 我有一个在 a 中添加 删除 编辑记录的活动SortedMap 该活动作为以下活动的延伸实施ListActivity 我已经实现了自定义ArrayAdapter对于收藏品 Every ListView项目 对应于基础记录
  • 如何用LoaderManager自动重新查询

    我有一个应用程序显示来自 SQLite DB 的数据 并且数据不断变化 所以显然 我认为我应该使用 LoaderManager 来显示数据 我读过一些关于将 LoaderManager 与 SQLite 结合使用的内容 然后看到了亚历克斯

随机推荐