Android Fragment onAttach()已弃用

我已经更新了我的应用程序使用最新的支持库(版本23.0.0),我发现他们弃用了Fragment类的onAttach()函数。

而不是:

onAttach (Activity activity)

现在是:

onAttach (Context context)

由于我的应用程序使用的活动传递之前弃用,我认为一个可能的解决方案是:

@Override
public void onAttach(Context context) {
super.onAttach(context);
activity = getActivity();
}

这是正确的做法吗?

更新:

如果我运行一个API低于23的设备,新的onAttach()甚至没有被调用。我希望这不是他们的本意!

更新2:

该问题已解决与SDK的最新更新。

我已经测试了我的API 22设备和onAttach(上下文)正在被调用。

点击在这里来跟踪我几周前打开的错误报告和谷歌的人的答案。

161711 次浏览

Activity是一个上下文,所以如果你可以简单地检查上下文是否是一个Activity,并在必要时强制转换它。

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


Activity a;


if (context instanceof Activity){
a=(Activity) context;
}


}

一些人声称新的Context重写永远不会被调用。我做了一些测试,找不到一个场景,这是真的,根据源代码,它不应该是真的。在我测试的所有情况下,无论是在SDK23之前还是之后,都调用了onAttachActivityContext版本。如果你能找到一个不是这样的场景,我建议你创建一个示例项目来说明这个问题和向Android团队报告

更新2:我只使用Android支持库片段,因为bug在那里得到更快的修复。似乎只有当你使用框架片段时,上面的覆盖没有被正确调用的问题才会显现出来。

目前在onAttach片段代码中,尚不清楚Context是否是当前活动:源代码

public void onAttach(Context context) {
mCalled = true;
final Activity hostActivity = mHost == null ? null : mHost.getActivity();
if (hostActivity != null) {
mCalled = false;
onAttach(hostActivity);
}
}

如果你看一下getActivity,你会看到相同的调用

/**
* Return the Activity this fragment is currently associated with.
*/
final public Activity getActivity() {
return mHost == null ? null : mHost.getActivity();
}

因此,如果你想确保你正在获得活动,然后使用getActivity()(在onAttach在你的Fragment中),但不要忘记检查null,因为如果mHostnull,你的活动将是null

如果你使用框架片段,而设备的SDK版本低于23,OnAttach(Context context)将不会被调用。

我使用支持片段代替,所以弃用是固定的,并且onAttach(Context context)总是被调用。

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


Activity activity = context instanceof Activity ? (Activity) context : null;
}

下载最新的支持库与sdk管理器和包括

compile 'com.android.support:appcompat-v7:23.1.1'

在它。App并设置编译版本为API 23

这是谷歌的另一个巨大变化…建议的修改:用onAttach(Context context)替换onAttach(Activity activity)在旧的api上使我的应用程序崩溃,因为onAttach(Context context)不会在本机片段上被调用。

我使用本机片段(android.app.Fragment),所以我必须做以下工作,使它再次工作在旧的api (<23)。

以下是我所做的:

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


// Code here
}


@SuppressWarnings("deprecation")
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);


if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
// Code here
}
}

下面的答案与Android开发者网站上Fragments教程中出现的弃用警告有关,可能与上面的帖子无关。

我在教程课上使用了这个代码,它确实起作用了。

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


Activity activity = getActivity();

我担心活动可能是空的,正如文档所述。

getActivity

FragmentActivity getActivity () 返回这个片段当前关联的FragmentActivity。

但是main_activity上的onCreate清楚地显示了片段已加载,因此在此方法之后,从片段调用get activity将返回main_activity类。

.beginTransaction < p > getSupportFragmentManager () () 阀门(R.id.fragment_container firstFragment) .commit (); < / p >

我希望我是对的。我绝对是个新手。

你可能正在使用android.support.v4.app.Fragment。对于这个方法,不使用onAttach方法,只需使用getActivity()来获得与片段关联的FragmentActivity。否则你可以使用onAttach(Context context)方法。

尽管在大多数情况下,拥有onAttach(Context)似乎就足够了,但有一些电话(如:小米Redme Note 2)没有被调用,因此它会导致nullpointerexception。所以为了安全起见,我建议也不要使用被弃用的方法:

// onAttach(Activity) is necessary in some Xiaomi phones
@SuppressWarnings("deprecation")
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
_onAttach(activity);
}


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


private void _onAttach(Context context) {
// do your real stuff here
}

当我有用户定义的接口“TopSectionListener”时,这对我有用,它的对象activitycommander:

  //This method gets called whenever we attach fragment to the activity
@Override
public void onAttach(Context context) {
super.onAttach(context);
Activity a=getActivity();
try {
if(context instanceof Activity)
this.activitycommander=(TopSectionListener)a;
}catch (ClassCastException e){
throw new ClassCastException(a.toString());}


}