【问题标题】:Fragment - how can getActivity() return null AFTER onAttach片段 - getActivity() 如何在 onAttach 之后返回 null
【发布时间】:2013-07-18 16:16:31
【问题描述】:

我有一个管理器类,它是一个保留的片段,它包含未保留的片段和该片段的 AsyncTasks。

屏幕旋转后,我想将新片段和正在运行/已完成的任务相互链接,并使用任务提供的数据更新片段。

现在在我保留的片段中,我有以下代码:

@Override
public void onAttach(Activity activity)
{
    mFragStatePagerAdapter.update(activity.getSupportFragmentManager());
    
    Debugger.Debug(DEBUG, getClass(), "ON_ATTACH_0: parentActivity: {" + 
        (activity != null ? activity.hashCode() : "NULL") + "}");

    for (int i = 0; i < mFragStatePagerAdapter.getFragmentListSize(); i++)
    {
        Frag f = mFragStatePagerAdapter.tryGetItem(i);
        
        if (f != null)
            f.onAttach(activity);

        // alternatively I tried following as well
        // if (f != null)
        //     activity.getSupportFragmentManager().beginTransaction().attach(f).commit();
        
        Debugger.Debug(DEBUG, getClass(), "ON_ATTACH_1: this: " + 
            this.hashCode() + " fragment: " + f + ", 
            parentActivity: {"+ (f.getActivity() != null ? f.getActivity().hashCode() : "NULL") + "}");
    }
    
    
    for (int i = 0; i < mTasks.size(); i++)  
    {
        if (mTasks.get(i) != null)
        {
            Frag f = getFragment(i);
            mTasks.get(i).attach(f, mTaskCallbacks.get(i));
            if (mTasks.get(i).getStatus() == Status.FINISHED)
                mTasks.get(i).deliverResult();
        }
    }
    
    super.onAttach(activity);
}

解释:

  • Frag...这是一个扩展 Fragment 的类
  • mFragStatePagerAdapter...它是一个扩展的 FragmentStatePagerAdapter,具有按索引获取片段的功能...

现在我的问题在于(缩短的)调试输出:

ON_ATTACH_0:父活动:{1123400376}

ON_ATTACH_1:this:1121944544 片段:ExerciseViewFragment{42e2da98},parentActivity:{NULL}

那么,为什么在调用f.onAttach(activity) 之后,f.getActivity() 返回 null?我没有在我的扩展片段类中覆盖onAttach,所以这不是原因......

【问题讨论】:

  • 我认为你不应该自己打电话给f.onAttach(activity);
  • 我添加了一个替代方案,因为这让我想到了以下想法:使用 activity.getSupportFragmentManager().beginTransaction().attach(f).commit(); 代替......但不幸的是它也不起作用......所以如果 onAttach 不应该像这样使用那,我怎样才能实现我的目标?片段应再次附加到新活动...以便我可以更新片段的数据...
  • 您的适配器实现有些可疑,因为如果这些片段是当前在 ViewPager 中可见的片段,则它们应该具有有效的活动引用(自己调用 onAttach 是错误的)。无论如何,与其保留的片段尝试将数据发送到其他片段,为什么不将其设为简单的数据持有者并让其他片段直接从它们的实现中使用它。
  • 实际上,我也想过这种方式......现在我有一个保留的片段来保存任务,如果任务存在,寻呼机片段会在保留的片段中查找,或者将它们自己附加到这个任务或者如果它已经完成,请使用此任务的数据或创建一个新线程并将其添加到保留的片段中......这样到目前为止一切似乎都工作......所以感谢你指出我正确的方向......花费一整天都在为 pager + pageindicator + Fragments 编写一个可重用的管理器,这些管理器在一个线程中加载它们的数据......现在我有了一些东西,所以谢谢

标签: android android-activity fragment


【解决方案1】:

我认为你的问题在于调用

super.onAttach(activity);

在您的 onAttach 方法的末尾。 在这个方法中首先调用它,像这样:

@Override
public void onAttach(Activity activity)
{
     super.onAttach(activity)

     // and here goes your code
     [...]
}

【讨论】:

  • 我不再使用此代码,但我记得那是必要的。我以前不得不这样做。问题不在于,保留的片段引发了异常,手动附加的片段(您可以在代码中看到)被附加并且直接在没有返回它们刚刚附加到的活动之后......
【解决方案2】:

根据https://developer.android.com/reference/android/support/v4/app/Fragment.html#getActivity()的文档

如果片段与上下文相关联,getActivity() 可能会返回 null。

根据本文档https://developer.android.com/reference/android/support/v4/app/Fragment.html#onAttach(android.app.Activity)onAttach(Activity activity) 已弃用,因此请改用onAttach(Context)

【讨论】:

  • 确实如此,但前提是您使用的是最新版本的支持库。问题是在 2013 年提出的,当时它的工作方式有点不同:-)
猜你喜欢
  • 1970-01-01
  • 2017-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-30
  • 1970-01-01
  • 2012-07-22
相关资源
最近更新 更多