片段中的OnLoadFinished导致NullPointerException,无法修复或重现崩溃

时间:2014-07-26 13:52:08

标签: android android-fragments android-contentprovider android-cursoradapter

我有应用程序在哪里使用fragmentManager我管理片段。其中一个片段列表是WikiItemsFragment

我的问题是OnLoadFinished中的NullPointerException

x.x.fragments.WikiItemsFragment.onLoadFinished (WikiItemsFragment.java:97)
x.x.fragments.WikiItemsFragment.onLoadFinished (WikiItemsFragment.java:33)

第33行描述了这个片段类, 第97行描述adapter.swapCursor(cursor);

嗯,我仍然无法重现问题,但我知道它发生在撞车事故中,而且只发生在我身上几次。 我仍然不明白我的应用程序在OnLoadFinished方法中崩溃我做错了什么 我怎么能强迫我的碎片崩溃?我怎么能修复它甚至重现它?我正在研究Nexus 4。

public class WikiItemsFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {

public static String TAG = WikiItemsFragment.class.getSimpleName();
private ListView listView;
private TextView emptyView;
private TextView wikiItemsInfoBar;
private CursorAdapter adapter;
private Uri uri;
private String[] array;


public static WikiItemsFragment getInstance(Uri contentUri, String[] projectionArray) {
    WikiItemsFragment f = new WikiItemsFragment();
    Bundle bundle = new Bundle();
    bundle.putParcelable("uri", contentUri);
    bundle.putStringArray("array", projectionArray);
    f.setArguments(bundle);
    return f;
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_wiki_items, null);

    listView = (ListView) view.findViewById(R.id.listView);
    emptyView = (TextView) view.findViewById(R.id.empty_list);
    emptyView.setTypeface(Core.robotoRegular);
    wikiItemsInfoBar = (TextView) view.findViewById(R.id.wiki_items_info_bar);
    wikiItemsInfoBar.setTypeface(Core.robotoRegular);

    return view;
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    uri = getArguments().getParcelable("uri");
    array = getArguments().getStringArray("array");

    if (uri == WikiItemsOffensiveTable.CONTENT_URI)
        adapter = new WikiItemsOffensiveAdapter(getActivity());
    else if (uri == WikiItemsDefensiveTable.CONTENT_URI)
        adapter = new WikiItemsDefensiveAdapter(getActivity());
    else if (uri == WikiItemsOtherTable.CONTENT_URI)
        adapter = new WikiItemsOtherAdapter(getActivity());
    else if (uri == WikiItemsUsableTable.CONTENT_URI)
        adapter = new WikiItemsUsableAdapter(getActivity());
    else if (uri == WikiItemsSpecialTable.CONTENT_URI)
        adapter = new WikiItemsSpecialAdapter(getActivity());
    else if (uri == WikiItemsArtifactTable.CONTENT_URI)
        adapter = new WikiItemsArtifactAdapter(getActivity());

    listView.setAdapter(adapter);

}

@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
    return new CursorLoader(getActivity(), uri, array, null, null, null);
}

@Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {

    adapter.swapCursor(cursor);
}

@Override
public void onLoaderReset(Loader<Cursor> cursorLoader) {
    adapter.swapCursor(null);
}

@Override
public void onResume() {
    super.onResume();
    getLoaderManager().initLoader(0, null, this);
}

@Override
public void onPause() {
    super.onPause();
    adapter.swapCursor(null);
}
}

2 个答案:

答案 0 :(得分:1)

由于CursorAdapter可以对方法null使用swapCursor值,因此必须在设置适配器之前调用onLoadFinished。

实际上看起来你在这里发了很多ifs:

if (uri == WikiItemsOffensiveTable.CONTENT_URI)
    adapter = new WikiItemsOffensiveAdapter(getActivity());
else if (uri == WikiItemsDefensiveTable.CONTENT_URI)
    adapter = new WikiItemsDefensiveAdapter(getActivity());
else if (uri == WikiItemsOtherTable.CONTENT_URI)
    adapter = new WikiItemsOtherAdapter(getActivity());
else if (uri == WikiItemsUsableTable.CONTENT_URI)
    adapter = new WikiItemsUsableAdapter(getActivity());
else if (uri == WikiItemsSpecialTable.CONTENT_URI)
    adapter = new WikiItemsSpecialAdapter(getActivity());
else if (uri == WikiItemsArtifactTable.CONTENT_URI)
    adapter = new WikiItemsArtifactAdapter(getActivity());

但是如果还有什么呢?您必须获取另一个uri(可能为null,如果未设置args),则创建默认适配器或记录错误。像这样:

if (uri == WikiItemsOffensiveTable.CONTENT_URI)
    adapter = new WikiItemsOffensiveAdapter(getActivity());
else if ...
...
else
    Log.e("Oh no", "The uri was not recognized. Adapter was not created");

答案 1 :(得分:0)

找到解决方案,但我并没有完全理解发生了什么......我不得不将if语句更改为UriMatcher。不知何故比较uri与字符串uri总是不起作用。有时我将element1element1进行比较,它说,嘿,它不一样!很奇怪。