我花了将近两天的时间试图弄清楚为什么会这样,但到目前为止找不到解决办法。所以我在这里发帖。
我有一个非常通用的Sliding Tab,它是在Eclipse中为较新的Android API创建的。在其中一个滑动标签中,我调用了ListFragment。此ListFragment使用CursorLoader加载一些数据。
现在当应用程序退出时,它会给出:05-28 11:34:00.327:E / AndroidRuntime(31994):java.lang.RuntimeException:无法销毁活动{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();
}
}
}
答案 0 :(得分:0)
最后我找到了答案,它是代码中最意想不到的地方。我仍然不理解这些机制,但我已经确认它是有效的。
我正在使用Android 4.0.3和支持库rev 12。
原来我的代码非常好,我甚至不需要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开发完全摆脱或完全放弃XML。