为什么我的片段没有附加到活动错误?

时间:2015-12-30 20:05:42

标签: android android-fragments

我有一个在我的Activity中触发回调方法的线程,它有一个片段。然后,Activity调用Fragment中的方法以使用新信息刷新UI。在该方法中,调用getString()。当调用getstring()时,我得到一个'Fragment not Attached to Activity error'。此UI刷新错误被保护runOnUIThread。片段的添加方式如下:

 FragmentManager fm = getSupportFragmentManager();
        fm.beginTransaction()
            .add(fragmentContainerID, fragment, tag)
            .commit();
        fm.executePendingTransactions();

活动使用两个不同的布局文件进行水平和垂直方向。它们是两种布局中的两个片段容器。它们在水平和垂直布局中具有相同的名称,但它们彼此不匹配。在第一次创建Activity时,使用上面的代码添加片段。在方向更改时,片段会自动添加到布局中,因为片段容器在垂直和水平方向上具有相同的ID。 当savedInstanceState不为null时,我使用

获得对片段的引用
fm.findFragmentByTag

有谁能告诉我我做错了什么?片段被明显地添加到Activity中,并且在此线程回调发生之前几分钟就过去了,所以我看不到片段是如何“附加”的。

编辑:叹了口气,经过一些调试我发现以这种方式添加片段非常好。 Activity中的其他代码(我注册了两次回调)导致我的片段没有附加错误。如果有人读到这个错误,请记住这个问题可以从其他地方触发。此外,您必须在片段中将setRetainInstance设置为true以避免重新创建它。单独的标签不会那样做。

3 个答案:

答案 0 :(得分:1)

每个容器添加一个片段,因此如果您使用.add(fragmentContainerID, fragment, tag),请首先确保fragmentContainerID对于添加的每个片段都不同。

然而,这些问题通常是由于对如何处理方向变化的误解造成的。当你改变方向并让oncreate处理添加时:你得到一个相同类型的新片段这意味着如果你的后台任务有你的片段的引用 - 它有一个引用(现已分离)片段。您需要做的是确保将相同的片段添加到标记(而不是新实例)。要做到这一点,当我们只恢复状态时,不要(重新)创建一个片段实例

public class MyActivity ... {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    FragmentManager fm = getSupportFragmentManager();
    if (savedInstanceState == null) {
        MyFragment frag = new MyFragment();
        frag.setArguments( getIntent().getExtras() ); //if it takes params
        fm.beginTransaction().add(fragmentContainerID, frag, tag).commit();
    }

    //after this point a call to MyFragment frag = (MyFragment) fm.findFragmentByTag(tag); should always return the correct fragment
}

对于你的任务来说,当它执行回调以更新UI时(而不是保持对它的引用),可能也是一个明智的想法。根据您设置任务的方式,只需更改FragmentManager fm = getSupportFragmentManager();然后创建任务,再将其作为onPostExecute

的一部分进行调用

答案 1 :(得分:0)

当更改方向时,片段会自动添加到FragmentManager并忘记自己的标记!!

使用此代码查找您的片段:

FragmentManager fragmentManager= getSupportFragmentManager();
for (Fragment fragment : fragmentManager.getFragments())
{
    if(fragment instanceof MyFragment)
        myFragment = (MyFragment)fragment;
}

答案 2 :(得分:0)

在找到方向更改后的片段后,尝试分离它们,然后在任何操作之前重新连接它们。或者,如果这不起作用,请删除它们并添加它们。然后继续.....我甚至不得不在分离之后和附加之前将时间延迟几毫秒,以确保一切正常。