1

我正在创建一个应用程序,其中涉及多个片段作为操作栏上的选项卡。当我切换选项卡关闭应用程序时,我需要保持这些片段的进程运行(不是结束应用程序,但是当按下主页或返回时,我希望应用程序继续在后台运行)。因此,为了在选项卡之间切换时保持片段运行,我修改了 sdk 中的示例 TabListener 之一以显示和隐藏而不是附加和分离。代码是:

public static class TabListener<T extends Fragment> implements ActionBar.TabListener {
    private Fragment mFragment;
    private final Activity mActivity;
    private final String mTag;
    private final Class<T> mClass;
    private final Bundle mArgs;


    public TabListener(Activity activity, String tag, Class<T> clz) {
        this(activity, tag, clz, null);
    }

    public TabListener(Activity activity, String tag, Class<T> clz, Bundle args) {
        mActivity = activity;
        mTag = tag;
        mClass = clz;
        mArgs = args;

        // Check to see if we already have a fragment for this tab, probably
        // from a previously saved state.  If so, deactivate it, because our
        // initial state is that a tab isn't shown.
        mFragment = mActivity.getFragmentManager().findFragmentByTag(mTag);
        if (mFragment != null && !mFragment.isHidden()) {
            FragmentTransaction ft = mActivity.getFragmentManager().beginTransaction();
            ft.hide(mFragment);
            ft.commit();
        }
    }

    public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
        if (mFragment == null) {
            mFragment = Fragment.instantiate(mActivity, mClass.getName(), mArgs);
            ft.add(android.R.id.content, mFragment, mTag);
        } else {
            ft.show(mFragment);
        }
    }

    public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
        if (mFragment != null) {
            ft.hide(mFragment);
        }
    }

    public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
        // User selected the already selected tab. Usually do nothing.
    }
}

选项卡是这样创建的:

    ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

    ActionBar.Tab aTab= actionBar.newTab().setText("Tab A").setTabListener(new TabListener<AFragment>(this, "AFrag", AFragment.class));
    actionBar.addTab(aTab);
    ActionBar.Tab bTab= actionBar.newTab().setText("Tab B").setTabListener(new TabListener<BFragment>(this, "BFrag", BFragment.class));
    actionBar.addTab(bTab);

所以这似乎有效,至少可以切换标签。有时这些片段会出现在彼此之上,尽管那是 TabListener 的不同实现,并且从那以后它就没有发生过,所以它现在可能已经消失了。我不知道它为什么会发生,所以我不知道如何复制它。

虽然关闭应用程序时它非常有问题。大多数情况下,当我按下 home 键时,应用程序仍然可以运行,并且当我再次打开它时它会运行。有时它不会,这很奇怪。按返回也会关闭应用程序,但再次启动它似乎会从头开始重新启动应用程序,这是不希望的。有时,当从该位置按下时,它会返回到先前运行的片段。

虽然它非常随机且不稳定。它何时起作用或不起作用是不可预测的。解决此问题以提高稳定性的最佳方法是什么,以便在关闭时继续运行,并且重新打开应用程序不会重新启动它?

4

2 回答 2

0

像活动一样,片段可以将它们的状态保存在一个 Bundle 中,当onCreate()被调用时它会被传入。您可以考虑保存状态,以便即使您的应用程序被杀死(为了内存)您也可以恢复它。

我也建议使用

ft.addToBackStack(null)
    .remove(CurrentFragment)
    .add(ToShowFragment)
    .commit()

这样您就可以使用popBackStack()来轻松处理添加和删除片段。另请注意replace(),由于未正确反转,因此无法从后台弹出堆栈(您将获得状态异常)

于 2012-08-26T01:54:35.633 回答
0

您可以尝试使用Fragment.setRetainInstance(true)来保留 Fragment,尽管这可能仅适用于方向更改,但文档有点不清楚。

没有我知道的方法可以保留碎片。也许您最好的选择是将您想要保留的所有内容保存到 Bundle 对象中Fragment.onSaveInstanceState(..),然后在Fragment.onCreate(..)或中读取此数据Fragment.onCreateView(..)

另一种我不太了解的替代方法是使用Fragment.SavedState类,它似乎与上面类似,只是您可以随时手动保存状态。这将需要您进行大量编码,但会给您更大的控制权

于 2012-08-26T10:44:15.813 回答