片段 - getArguments()返回一个空包

时间:2017-04-24 20:48:53

标签: android android-fragments android-lifecycle fragmentmanager

希望有人能帮助我理解这一点:

  1. 我正在使用单活动应用程序和许多在同一容器中替换的片段,我正在使用"不要保持活动&#的真实设备中测试我的应用程序34;选项已启用

  2. 添加新片段(使用FragmentTransaction replace()方法)时,我使用setArguments()方法将信息传递给新片段。它按预期工作,我可以在片段中使用getArguments()获取该信息。到目前为止一切都还不错......

  3. 在此之后,我将我的应用程序发送到后台。我看到堆栈中的所有碎片都被破坏了,再次按预期进行了

  4. 我将我的应用程序带到前台,在getArguments()方法中我得到一个空的Bundle(不是空,只是一个空对象),而不是带有我用过的数据的那个#2

  5. 根据Android文档,setArguments()中提供的参数将在片段销毁和创建中保留...所以,我的问题是:

    1. "是否会在片段销毁和创建过程中保留"包括我描述的场景?

    2. "不要保持活动"如果启用了getArguments() / setArguments(),那么该选项可能会搞乱吗?

    3. 有没有办法测试正确的片段创建/销毁除了"不要保持活动"选项?

    4. 正确保持片段参数的更好方法是什么?#34; alive"?我可以将它们保存在onSaveInstanceState()方法中,但想知道除此之外是否还有更多选项。

6 个答案:

答案 0 :(得分:2)

我想问题是你每次调用活动的onCreate时都会创建一个新的片段实例。假设您当前的代码如下所示:

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

    ...
    ...
    fragment = SampleFragment.newInstance("sample");
    getSupportFragmentManager()
            .beginTransaction()
            .replace(R.id.container, fragment, "sample_fragment_tag")
            .commit();
    ...
}

因此,每次重新创建活动时,都会创建一个新的片段实例并将其附加到活动。只有当savedInstanceStatenull时,您才应该避免这种情况并创建片段的新实例,这意味着您的活动刚刚创建。否则,将使用其参数以及活动实例来恢复已保存的片段实例:

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

    ...
    ...
    if (savedInstanceState == null) {
        fragment = SampleFragment.newInstance("sample");
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.container, fragment, "sample_fragment_tag")
                .commit();
    } else {
        fragment = (SampleFragment) getSupportFragmentManager().findFragmentByTag("sample_fragment_tag");
    }
    ...
}

希望,这就是你要找的东西。

答案 1 :(得分:1)

感谢大家的回答。我仍然不知道为什么我会遇到这个问题。我创建了一个示例项目来测试片段事务并将其发布在@Reyansh和@Björn问。这是一个非常简单的项目 - 猜猜是什么 - 我无法在该项目中重现该问题:每次重新创建活动时,getArguments()方法都会提供相同的Bundle。所以,它必须是我的项目中的其他东西导致这种奇怪的行为。

我决定将@jDur答案标记为正确答案,因为它为我的问题提供了一个很好的解释。

答案 2 :(得分:0)

我知道不要保持活动选项是为了在低内存条件下测试你的应用程序,当其他资源无法为你的应用程序提供服务时Android操作系统会杀死你的应用程序。 那时你有机会使用onSavedInstanceState来保存数据,并且在片段中你可以使用setRetainState(true) 根据我保存捆绑数据的经验是使用sharedPreferences。 在您从设置中卸载或清除应用程序数据或通过SharedPreference Editor以编程方式删除它时,SharedPreference永远不会被销毁。 有一点很清楚,如果活动被破坏,那么它的所有碎片肯定会被摧毁。 希望你明白我的意思。

答案 3 :(得分:0)

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/*Created by Foolish_Guy on 4/29/2017.*/                 

public class TestFragment extends Fragment {
private static final String USER_ID = "param1";
private static final String ARG_PARAM2 = "param2";

String userID;
String mParam2;

public static TestFragment newInstance(String param1, String param2) {
    TestFragment fragment = new TestFragment();
    Bundle args = new Bundle();
    Log.e("Data :", String.valueOf(param1));
    args.putString(USER_ID, param1);
    args.putString(ARG_PARAM2, param2);
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
        userID = getArguments().getString(USER_ID);
        mParam2 = getArguments().getString(ARG_PARAM2);
    }
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_layout, container, false);
    return view;
}

}

初始化片段时需要提供必需的参数。 您正在通过调用

初始化它
TestFragment frag = TestFragment.newInstance("UID", "TEXT");

一旦调用它,将设置Bundle参数

将调用onCreate (Bundle savedInstance)中的下一个, 现在Bundle不会是空的。

答案 4 :(得分:0)

onSaveInstanceState是销毁应用但仍在最近的应用列表中时保存数据的最佳位置。您可以节省足够的时间来重建应用在发送到后台时的外观以及用户离开应用的位置。用户将应用程序置于背景中两到三周,然后将其带到前面并微笑记住它在哪里。

在偏好设定状态下,您的应用用户会将手机放在墙上。他们将从最近的应用程序清除应用程序,然后重新启动然后永久地取消暂停您的应用程序,因为它一开始没有从最近的应用程序中删除,并且他们希望应用程序从头开始。我放松了吗?

答案 5 :(得分:0)

setRetainInstance(true);

片段的onCreate方法。在通过标记添加或替换来自SupportFragmentManager的片段get之前,如果片段值为null,则添加或替换为新片段。喜欢

Fragment fragment = fragmentManager.findFragmentByTag(tag);
if(fragment==null){
 fragmentManager.beginTransaction().replace(...
}