0

私はフラグメントにかなり慣れていないので、問題があります。

私の onResume() メソッドはデータベース ヘルパー クラスを呼び出します。このクラスはいくつかの単純なオブジェクトを次のリスナー メソッドに返します。

    @Override
public void onHistoryLoaded(List<Entry> entrieslist) {
    Logging.d(TAG, "onHistoryLoadedListener called");
    if (entrieslist != null) {
        this.entries = entrieslist;
        if (mAdapter == null) {
            Logging.d(TAG, "adapter is null, recreating");
            this.mAdapter = new HistoryAdapter(getActivity(),
                    R.layout.history_row, entrieslist);
            registerForContextMenu(lv);
            mAdapter.setNotifyOnChange(true);
            lv.setAdapter(mAdapter);
            mAdapter.notifyDataSetChanged();
        } else {
            mAdapter.clear();
            mAdapter.addAll(entries);

            mAdapter.notifyDataSetChanged();
        }

    } else {
        Logging.e(TAG, "onHistoryLoaded: returned entries are empty");
    }

}

ご覧のとおり、null の場合、インスタンス変数 mAdapter が初期化されます。これはこれまでのところうまくいきます。私の問題は、構成が変更されるとすぐに発生します (たとえば、ユーザーがランドスケープに入ると)。データは正常に表示されます (onResume および onHistoryLoaded も正常に呼び出され、アダプターが null であるため、新しく作成されたことが示されるため)。ただし、アダプターで .clear() を呼び出すと (ポートレート モードで正常に動作します)、mAdapter 変数インスタンスが null であるため、nullpointerexception が発生します。これはどのように起こりますか?バックグラウンドスレッドなどでは何もしません。この時点で null であってはなりません。

私はアイデアのatmを使い果たしています。前もって感謝します。

私の LogCat エラー:

02-05 00:17:22.430: E/HistoryFragment(25174): mAdapter is null?
02-05 00:17:22.430: W/System.err(25174): java.lang.NullPointerException
02-05 00:17:22.445: W/System.err(25174):        at com.sapps.savetodrive.HistoryFragment.cleanHistory(HistoryFragment.java:361)
02-05 00:17:22.445: W/System.err(25174):        at com.sapps.savetodrive.MainActivity.onOptionsItemSelected(MainActivity.java:103)
02-05 00:17:22.445: W/System.err(25174):        at android.app.Activity.onMenuItemSelected(Activity.java)
02-05 00:17:22.445: W/System.err(25174):        at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:351)
02-05 00:17:22.445: W/System.err(25174):        at com.android.internal.policy.impl.PhoneWindow.onMenuItemSelected(PhoneWindow.java)
02-05 00:17:22.450: W/System.err(25174):        at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java)
02-05 00:17:22.455: W/System.err(25174):        at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java)
02-05 00:17:22.455: W/System.err(25174):        at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java)
02-05 00:17:22.455: W/System.err(25174):        at com.android.internal.view.menu.MenuPopupHelper.onItemClick(MenuPopupHelper.java)
02-05 00:17:22.475: W/System.err(25174):        at com.android.internal.view.menu.ActionMenuPresenter$OverflowPopup.onItemClick(ActionMenuPresenter.java)
02-05 00:17:22.480: W/System.err(25174):        at android.widget.AdapterView.performItemClick(AdapterView.java)
02-05 00:17:22.480: W/System.err(25174):        at android.widget.AbsListView.performItemClick(AbsListView.java)
02-05 00:17:22.485: W/System.err(25174):        at android.widget.ListView.performItemClick(ListView.java)
02-05 00:17:22.485: W/System.err(25174):        at android.widget.AbsListView$PerformClick.run(AbsListView.java)
02-05 00:17:22.485: W/System.err(25174):        at android.widget.AbsListView$1.run(AbsListView.java)
02-05 00:17:22.485: W/System.err(25174):        at android.os.Handler.handleCallback(Handler.java)
02-05 00:17:22.490: W/System.err(25174):        at android.os.Handler.dispatchMessage(Handler.java)
02-05 00:17:22.490: W/System.err(25174):        at android.os.Looper.loop(Looper.java)
02-05 00:17:22.490: W/System.err(25174):        at android.app.ActivityThread.main(ActivityThread.java)
02-05 00:17:22.490: W/System.err(25174):        at java.lang.reflect.Method.invokeNative(Native Method)
02-05 00:17:22.490: W/System.err(25174):        at java.lang.reflect.Method.invoke(Method.java)
02-05 00:17:22.490: W/System.err(25174):        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java)
02-05 00:17:22.495: W/System.err(25174):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java)
02-05 00:17:22.495: W/System.err(25174):        at dalvik.system.NativeStart.main(Native Method)

次のコードは、エラーが発生する場所です (少し再構築され、 mAdapter.clear() で発生します)。これは mAdapter == null を返します。TRUE です。

    public void cleanHistory() {
    if (mAdapter == null)
        Logging.e(TAG, "ADAPTER IS NULL WHEN CLEANING?!");
    else {
        mAdapter.clear();
        lastUndoAction = FLAG_UNDO_CLEANALL;
        mUndoBarController.showUndoBar(false,
                getString(R.string.item_allremoved), null);
    }
}

onResume ..

    @Override
public void onResume() {
    super.onResume();
    if (lv != null && helper != null) {

        Logging.d(TAG, "onResume(), lv and helper aren't null");
        helper.getAllEntries();
        // adapter.notifyDataSetChanged();
    }
}
4

1 に答える 1

1

これで修正されました。質問は実際には別の場所にありました。Android は、フラグメント オブジェクトの独自のインスタンスをインスタンス化しているようです。つまり、ビューページャーによって取得されたフラグメントインスタンスでの OnOptionsItemCrated() での私の呼び出しは、基本的にフラグメントの空のインスタンスであり、onAttach() onActivityCreated() が呼び出されていませんでした。まだどのアクティビティにも関連付けられていません。したがって、私の「回避策」(この特に愚かな問題の私見) は、ここで提案されている解決策を使用することでした: Switcher の getFragmentByTag

それが行うことは、基本的にビューページャー内で「生成されたタグを生成」して、現在表示されている(および添付されている)フラグメントをフラグメントマネージャーから取得することです。

private String getFragmentTag(int pos){
    return "android:switcher:"+R.id.pager+":"+pos;
}

したがって、onOptionsItemSelected の私のソリューションは最終的に次のようになります。

    case R.id.menu_cleanhistory:
            ((HistoryFragment) MainActivity.this.getSupportFragmentManager()
                    .findFragmentByTag(
                            "android:switcher:" + R.id.viewpager + ":1"))
                    .cleanHistory();
           return true;

信じられないかもしれませんが、うまくいきます。

于 2013-02-05T15:38:59.523 に答える