0

なぜこれが起こっているのかを理解するためにほぼ2日を費やしましたが、これまでのところ解決策を見つけることができませんでした. だから私はここに投稿しています。

新しい Android API 用に Eclipse で作成されたかなり一般的なスライド タブがあります。スライド タブの 1 つの中で、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 開発が完全に取り除かれるか、XML が完全になくなることを望みます..

于 2013-05-28T19:45:29.053 に答える