Android Fragment onAttach()已弃用

Tar*_*ury 317 android android-fragments

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

代替:

onAttach (Activity activity)
Run Code Online (Sandbox Code Playgroud)

下雪了:

onAttach (Context context)
Run Code Online (Sandbox Code Playgroud)

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

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    activity = getActivity();
}
Run Code Online (Sandbox Code Playgroud)

这是正确的方法吗?

更新:

如果我运行API低于23的设备,则甚至不会调用新的onAttach().我希望这不是他们打算做的!

更新2:

问题已通过SDK的最新更新得到解决.

我已经在我的API 22设备上进行了测试,并且正在调用onAttach(Context).

点击此处查看我几周前开设的错误报告以及Google员工的答案.

Kuf*_*ffs 328

Activity是一个上下文,所以如果你只是检查上下文是一个Activity并在必要时强制转换它.

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

    Activity a;

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

}
Run Code Online (Sandbox Code Playgroud)

更新:有些人声称Context永远不会调用新的覆盖.我已经完成了一些测试,并且无法找到这样的场景,根据源代码,它永远不应该是真的.在我测试的所有情况下,SDK23之前和之后,都调用了它们ActivityContext版本onAttach.如果您可以找到不是这种情况的场景,我建议您创建一个示例项目来说明问题并将其报告给Android团队.

更新2:我只使用Android支持库片段,因为错误在那里更快修复.如果你使用框架片段,那么上面的问题似乎没有被正确调用覆盖.

  • Buddy有同样的问题......`onAttach(Context)`似乎甚至没有被调用. (6认同)
  • 不是真正的解决方案,因为带有上下文的onAttach与onAttach with activity不同.如果在onAttach中有一些初始化代码,并且活动作为参数,则此更改将不起作用. (5认同)
  • 不,它不起作用,至少在我的情况下.我不在onAttach中使用activity或context,我做初始化.我已经尝试将onAttach替换为具有上下文的活动,并且不会以相同的方式调用它.所以他们不是那么容易互换的. (2认同)
  • 我已经完成了我的代码,我可以验证是否可以不调用`onAttach(context)`. (2认同)
  • 在我的情况下,如果我们重新启动之前由系统清除的活动,则不会调用onAttach().但它并不总是这样.我在onAttach(Context上下文)中初始化了WeakReference,refActivity = new WeakReference <>((AppCompatActivity)context).它偶尔会在onCreateView()中抛出NullPointerException. (2认同)

Yoa*_*uet 43

这是谷歌从另一个巨大的变化......所建议的修改:更换onAttach(Activity activity)onAttach(Context context),因为我坠毁在旧的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
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 38

如果使用框架片段且设备的SDK版本低于23,则OnAttach(Context context)不会被调用.

我改为使用支持片段,因此弃用是固定的并且onAttach(Context context)总是被调用.


roy*_*oyB 11

目前来自onAttachFragment代码,目前尚不清楚Context当前活动是否是:源代码

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

如果你看一下,getActivity你会看到同一个电话

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

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


Gav*_*iel 7

虽然看起来在大多数情况下它已经足够了onAttach(Context),但有一些手机(即:小米 Redme Note 2)没有被调用,因此会导致 NullPointerExceptions。因此,为了安全起见,我建议也保留已弃用的方法:

// 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
}
Run Code Online (Sandbox Code Playgroud)


wor*_*ked 6

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

    Activity activity = context instanceof Activity ? (Activity) context : null;
}
Run Code Online (Sandbox Code Playgroud)