如果在片段代码中没有覆盖onAttach(),该怎么办?

时间:2017-09-21 05:40:08

标签: android

根据片段生命周期onAttach()onCreate()之前调用,以便为片段分配宿主活动。所以,我想知道如果没有覆盖它会是什么。是否已存在所有片段回调的默认定义?

2 个答案:

答案 0 :(得分:2)

来自documentation

  

void onAttach(活动活动)

     一旦片段与其活动相关联,就会调用

。此方法在API级别中已弃用   23.改用onAttach(Context)。

     

如果重写此方法,则必须调用超类   实施

     

void onAttach(上下文关联)

     

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

这是片段的生命周期设计。如果不重写该方法,没有任何错误。

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

不,您需要自己创建片段回调。通常会覆盖onAttach()方法,以确保片段的父活动正在实现片段回调。这样的事情(在Communicating with Other Fragments阅读更多内容):

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");
        }
    }

    ...
}

当父活动未实施OnHeadlineSelectedListener时,应用程序将崩溃并抛出must implement OnHeadlineSelectedListener。因此,它会阻止您在代码中引入逻辑错误。

更新

onAttach()的目的是什么?

  

根据片段生命周期onAttach()在onCreate()之前调用   这样它就可以为片段分配主机活动。

实际意义是什么?

简单回答:它是片段的生命周期,我们可以知道片段何时附加到它的父母活动上。

更多详情:

来自以下source code of onAttach()

/**
 * 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

关于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;

但是如果我们扫描所有源代码片段,我们就无法获得mhost初始化的任何线索。

我们知道,从Fragment生命周期图中可以看出,添加片段时生命周期就开始了:

enter image description here

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

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

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

检查方法moveToState()中的FragmentManager source code at line 1200 to 1229

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);
}

现在我们知道Fragment的mHostonAttach()已初始化并由FragmentManager调用。

答案 1 :(得分:0)

如果你不打电话给OnAttach(),什么都不会发生。如果在片段附加到其活动或上下文时想要执行某些操作,则为您提供生命周期方法。

但是,片段类确实有OnAttach的默认实现(它没有做任何事情)。如果您好奇,请查看source code