0

我花了将近两天的时间试图弄清楚为什么会发生这种情况,但到目前为止找不到解决方案。所以我把它贴在这里。

我有一个非常通用的滑动选项卡,它是在 Eclipse 中为较新的 Android API 创建的。在其中一个滑动选项卡中,我称之为 ListFragment。这个 ListFragment 使用 CursorLoader 来加载一些数据。

现在当应用程序退出时,它给出:05-28 11:34:00.327: E/AndroidRuntime(31994): java.lang.RuntimeException: Unable to destroy activity {com.example.myapp/com.example.myapp.main. HomeActivity}:java.lang.NullPointerException

我曾尝试使用 ChildFragmentManager 以及最新的支持包,但无济于事。

这是调用另一个片段的唯一选项卡,否则仅调用静态 XML 内容的其余选项卡工作正常。如果我删除此选项卡,应用程序工作正常。

据我了解,我需要在应用程序退出之前销毁 CursorLoader 或以某种方式分离此特定片段。CursorLoader 似乎被破坏了,错误在 HomeActivty 中被捕获。也许我应该在 HomeActivity 中调用 onDestroy,但真的不知道如何以及在哪里。

调用 HomeActivity 的代码非常标准:

ViewPager mViewPager;
private static final String DEBUG_TAG = "MY APP"; 

private static boolean logged_in;

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

    sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
    logged_in = sharedPrefs.getBoolean("logged_in", false);

    Log.v(DEBUG_TAG, "logged_in: " + logged_in);

    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

    mViewPager = (ViewPager) findViewById(R.id.pager);
    mViewPager.setAdapter(mSectionsPagerAdapter);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.home, menu);
    return true;
}


public class SectionsPagerAdapter extends FragmentPagerAdapter {

    public SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        Fragment fragment;

        switch(position) {
        case 0:
              fragment = new MySectionFragment();
            break;
        case 1:
                ...

从 FragmentActivity 调用 ListFragment 的代码如下:

public static class MySectionFragment extends Fragment {
    public MySectionFragment() {}

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

    public void onDestroyView() {
        super.onDestroyView(); 
        Fragment fragment = (getFragmentManager().findFragmentById(R.id.fragment_my_section));

        if (fragment != null) {
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            ft.remove(fragment);
            ft.commitAllowingStateLoss();   
        }
    }
}
4

1 回答 1

0

最后我找到了答案,它在代码中最意想不到的地方。我仍然不了解机制,但我已经彻底确认它有效。

我正在使用带有支持库 rev 12 的 Android 4.0.3。

结果证明我的代码非常好,我什至不需要 onDestroyView()。视图被破坏并重新生成正常。无需处理 FragmentManager、SupportFragmentManager 或 ChildSupportFragmentManager。选择可滑动选项卡时在 Eclipse 中生成的默认代码就可以了。

我进行更改的唯一地方是 XML 模板。我将 android:id 从“fragment”部分移动到“RelativeLayout”部分。

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout
    android:id="@+id/fragment_my_section"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:paddingTop="4dp"
    android:background="@drawable/bg"> 

<ListView
    android:id="@android:id/list"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:drawSelectorOnTop="false"
    android:cacheColorHint="#00000000"/>

<fragment
    android:name="com.example.MyFragmentActivity"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
</fragment>

</RelativeLayout>

以前,id 位于“片段”部分。这是在 XML 文件中没有定义 RelativeLayout 和 ListView 的时候。

不用说,我讨厌这个 Android 开发世界中的 XML。大多数时候它一直是一个浪费我时间的 XML 文件,无一例外。IDE 也不能很好地捕捉这些 XML 问题。我希望 Android 开发完全摆脱或 XMLs ..

于 2013-05-28T19:45:29.053 回答