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");
    }

}

如您所见,如果我的实例变量 mAdapter 为空,则它会被初始化。到目前为止,这很好用。一旦配置更改(例如用户进入风景),我的问题就会出现。数据显示得很好(因为 onResume 和 onHistoryLoaded 也被调用得很好,并告诉适配器已经为空,因此是新创建的)。但是,当我在适配器上调用 .clear() (在纵向模式下工作正常)时,我得到一个空指针异常,因为 mAdapter 变量实例为空。这怎么可能发生?我在后台线程或其他东西中什么都不做。此时不应为空。

我的想法已经用完了。提前致谢。

我的 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);
    }
}

继续..

    @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() 调用(由 viewpager 检索)基本上是片段的空实例,它没有调用 onAttach() onActivityCreated() 东西,因为它是'尚未附加到任何活动。所以我的“解决方法”(对于这个特别愚蠢的问题恕我直言)是使用这里建议的解决方案:getFragmentByTag from Switcher

它的作用基本上是在 viewpager 中“生成生成的标签”,以从片段管理器中检索当前显示的(和附加的)片段。

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 回答