Android Fragment onAttach()已弃用

时间:2015-08-18 21:40:48

标签: android android-fragments

我已经更新了我的应用程序以使用最新的支持库(版本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(Context)。

点击here,按照我几周前开设的错误报告以及Google员工的回答。

10 个答案:

答案 0 :(得分:320)

活动是一个上下文,所以如果您只是检查上下文是一个活动并在必要时投射它。

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

    Activity a;

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

}

更新:有些人声称永远不会调用新的Context覆盖。我已经完成了一些测试,并且无法找到这样的场景,根据源代码,它永远不应该是真的。在我测试的所有情况下,无论是在SDK23之前还是之后,都会调用ActivityContext onAttach版本的(defun temp-edit-docstring () "Edit docstring in python-mode. " (interactive "*") (let ((orig (point)) (pps (parse-partial-sexp (point-min) (point)))) (when (nth 3 pps) (let* (;; relative position in string (relpos (- orig (+ 2 (nth 8 pps)))) (beg (progn (goto-char (nth 8 pps)) (skip-chars-forward (char-to-string (char-after)))(push-mark)(point))) (end (progn (goto-char (nth 8 pps)) (forward-sexp) (skip-chars-backward (char-to-string (char-before))) (point))) (docstring (buffer-substring beg end))) (kill-region beg end) (set-buffer (get-buffer-create "Edit docstring")) (erase-buffer) (switch-to-buffer (current-buffer)) (insert docstring) (python-mode) (goto-char relpos))))) 。如果您可以找到不是这种情况的情况,我建议您创建一个示例项目来说明问题并report it to the Android team

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

答案 1 :(得分:43)

这是Google的另一项重大变化...建议的修改:将onAttach(Activity activity)替换为onAttach(Context context)我的应用程序在较旧的API上崩溃,因为onAttach(Context context)将不会在本机片段上调用。< / p>

我正在使用本机片段(android.app.Fragment),因此我必须执行以下操作才能使其在旧版API(&lt; 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
    }
}

答案 2 :(得分:38)

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

我使用支持片段,因此修改了弃用并始终调用onAttach(Context context)

答案 3 :(得分:10)

目前来自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)但不要忘记检查{{ 1}}因为如果nullmHost,您的活动将为null

答案 4 :(得分:6)

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

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

答案 5 :(得分:3)

使用sdk管理器下载最新的支持库并包含

compile 'com.android.support:appcompat-v7:23.1.1'
在gradle.app中

并将编译版本设置为api 23

答案 6 :(得分:3)

虽然在大多数情况下似乎只有onAttach(Context),但有些电话(即:Xiaomi 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
}

答案 7 :(得分:1)

以下答案与Android开发人员网站上的Fragments教程中发生的弃用警告有关,可能与上述帖子无关。

我在教程课程中使用了这段代码,但确实有效。

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

    Activity activity = getActivity();

我担心活动可能会像文档所说的那样无效。

getActivity

FragmentActivity getActivity() 返回此片段当前与之关联的FragmentActivity。如果片段与Context相关联,则可能返回null。

但main_activity上的onCreate清楚地表明该片段已加载,因此在此方法之后,从片段调用get活动将返回main_activity类。

getSupportFragmentManager()。的BeginTransaction()                     .add(R.id.fragment_container,firstFragment).commit();

我希望我对此是正确的。我是一个绝对的新手。

答案 8 :(得分:1)

您可能正在使用android.support.v4.app.Fragment。为此而不是onAttach方法,只需使用getActivity()来获取与片段关联的FragmentActivity。否则,您可以使用onAttach(Context context)方法。

答案 9 :(得分:0)

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

Imports Newtonsoft.Json

        Dim dataSet As DataSet = New DataSet("dataSet")
        dataSet.[Namespace] = "NetFrameWork"
        Dim jsonTable As DataTable = New DataTable()
        Dim keyColumn As DataColumn = New DataColumn("Key")
        Dim valueColumn As DataColumn = New DataColumn("Value")
        jsonTable.Columns.Add(keyColumn)
        jsonTable.Columns.Add(valueColumn)
        dataSet.Tables.Add(jsonTable)

        jsonTable.TableName = "Data"

        For m = 1 To g
            Dim dataRow2 As DataRow = jsonTable.NewRow
            dataRow2("Key") = "Timestamp"
            dataRow2("Value") = testTimestamp(m)
            jsonTable.Rows.Add(dataRow2)

            For k = 1 To tagsCounter
                Dim dataRow1 As DataRow = jsonTable.NewRow
                dataRow1("Key") = testName(k)
                dataRow1("Value") = testValue(m, k)
                jsonTable.Rows.Add(dataRow1)
            Next k
        Next m