根据片段生命周期onAttach()
在onCreate()
之前调用,以便为片段分配宿主活动。所以,我想知道如果没有覆盖它会是什么。是否已存在所有片段回调的默认定义?
答案 0 :(得分:2)
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生命周期图中可以看出,添加片段时生命周期就开始了:
以编程方式,我们将片段添加到:
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的mHost
和onAttach()
已初始化并由FragmentManager
调用。
答案 1 :(得分:0)
如果你不打电话给OnAttach(),什么都不会发生。如果在片段附加到其活动或上下文时想要执行某些操作,则为您提供生命周期方法。
但是,片段类确实有OnAttach的默认实现(它没有做任何事情)。如果您好奇,请查看source code。