到达onLoadFinished回调时出现NullPointerException

时间:2015-04-16 02:12:43

标签: android

我查看了其他SO帖子,似乎没有解决我的问题(onCreateLoader回调中的光标有一个_id投影,这在另一个问题上解决了这里的问题)。从它的外观来看,我已经初始化了我的数据库并正确地连接了所有内容。

Fragment(初始化mSpinnerAdapter):

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        final View rootView = inflater.inflate(R.layout.fragment_main, container, false);

        int[] toViews = {R.id.spinner_top, R.id.spinner_bottom};

        mSpinnerAdapter = new android.support.v4.widget.SimpleCursorAdapter(
                getActivity(),
                android.R.layout.simple_spinner_item,
                null,
                null,
                toViews,
                0
        );
        mSpinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

        Spinner topYearSpinner =
                (Spinner) rootView.findViewById(R.id.spinner_year_top);
        topYearSpinner.setOnItemSelectedListener(this);

        Spinner bottomYearSpinner =
                (Spinner) rootView.findViewById(R.id.spinner_year_bottom);
        bottomYearSpinner.setOnItemSelectedListener(this);

        topYearSpinner.setAdapter(mSpinnerAdapter);
        bottomYearSpinner.setAdapter(mSpinnerAdapter);

DBHelper:

@Override
    public void onCreate(SQLiteDatabase db) {
        final String CREATE__TABLE = "CREATE TABLE IF NOT EXISTS " +
                Contract.Entry.TABLE_NAME + "(" +
                Contract.Entry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                Contract.Entry.COLUMN_YEAR + " INTEGER NOT NULL, " +
                Contract.Entry.COLUMN.OTHER_ + " INTEGER, " +
                Contract.Entry.COLUMN.OTHER1_ + " INTEGER);";

        //Building the table
        db.execSQL(CREATE__TABLE);
    }

LoaderCallbacks:

@Override
    public android.support.v4.content.Loader<Cursor> onCreateLoader(int id, Bundle args) {

        String[] projection = {Contract.Entry._ID, Contract.Entry.COLUMN_YEAR};
        String sortOrder = Contract.Entry.COLUMN_YEAR + " ASC";

        return new android.support.v4.content.CursorLoader(getActivity(),
                Contract.Entry.CONTENT_URI,
                projection, null, null, sortOrder);
    }

    @Override
    public void onLoadFinished(android.support.v4.content.Loader<Cursor> loader, Cursor data) {
        mSpinnerAdapter.swapCursor(data);
    }

    @Override
    public void onLoaderReset(android.support.v4.content.Loader<Cursor> loader) {
        mSpinnerAdapter.swapCursor(null);
    }

的ContentProvider:

public class Provider extends ContentProvider{

    private static final UriMatcher sUriMatcher = buildUriMatcher();
    private DbHelper mDbHelper;

    static final int _INDICES = 100;

    public static UriMatcher buildUriMatcher() {
        final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
        final String authority = Contract.AUTHORITY;

        matcher.addURI(authority, "_indices", _INDICES);

        return matcher;
    }

    @Override
    public boolean onCreate() {

        mDbHelper = new DbHelper(getContext());
        return true;
    }

合同:

public class Contract {

    public static final String AUTHORITY = "com.example.kent.mojito";
    public static final String PATH__INDICES = "_indices";
    public static final Uri BASE_CONTENT_URI = Uri.parse("content://" + AUTHORITY);

    public static final class Entry implements BaseColumns {
        public static final Uri CONTENT_URI = BASE_CONTENT_URI.buildUpon().appendPath(PATH__INDICES).build();

        public static final String CONTENT_TYPE =
                ContentResolver.CURSOR_DIR_BASE_TYPE+ "/" + AUTHORITY + "/" + PATH__INDICES;
        public static final String CONTENT_ITEM_TYPE =
                ContentResolver.CURSOR_ITEM_BASE_TYPE + "/" + AUTHORITY + "/" + PATH__INDICES;

        public static final String TABLE_NAME = "_indices";
        public static final String COLUMN_YEAR = "year";
        public static final String COLUMN_ = "";
        public static final String COLUMN_ = "";

        //Building a query for the Provider insert statement
        static Uri buildIndicesUri (long id) {
            return ContentUris.withAppendedId(CONTENT_URI, id);
        }
    }
}

logcat的:

04-15 17:26:13.845  24281-24281/com.example.kent.mojito E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.example.kent.mojito, PID: 24281
    java.lang.NullPointerException
            at android.widget.SimpleCursorAdapter.findColumns(SimpleCursorAdapter.java:328)
            at android.widget.SimpleCursorAdapter.swapCursor(SimpleCursorAdapter.java:345)
            at com.example.kent.mojito.ValueFragment.onLoadFinished(ValueFragment.java:133)
            at com.example.kent.mojito.ValueFragment.onLoadFinished(ValueFragment.java:35)
            at android.support.v4.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:427)
            at android.support.v4.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:395)
            at android.support.v4.content.Loader.deliverResult(Loader.java:104)
            at android.support.v4.content.CursorLoader.deliverResult(CursorLoader.java:73)
            at android.support.v4.content.CursorLoader.deliverResult(CursorLoader.java:35)
            at android.support.v4.content.AsyncTaskLoader.dispatchOnLoadComplete(AsyncTaskLoader.java:223)
            at android.support.v4.content.AsyncTaskLoader$LoadTask.onPostExecute(AsyncTaskLoader.java:61)
            at android.support.v4.content.ModernAsyncTask.finish(ModernAsyncTask.java:461)
            at android.support.v4.content.ModernAsyncTask.access$500(ModernAsyncTask.java:47)
            at android.support.v4.content.ModernAsyncTask$InternalHandler.handleMessage(ModernAsyncTask.java:474)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:212)
            at android.app.ActivityThread.main(ActivityThread.java:5135)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:877)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
            at dalvik.system.NativeStart.main(Native Method)

1 个答案:

答案 0 :(得分:1)

看起来你的初始化根本不好,如果你看一下SimpleCursorAdapter代码,交换方法是:

public void changeCursorAndColumns(Cursor c, String[] from, int[] to) {
    mOriginalFrom = from;
    mTo = to;
    // super.changeCursor() will notify observers before we have
    // a valid mapping, make sure we have a mapping before this
    // happens
    findColumns(c, mOriginalFrom);
    super.changeCursor(c);
}

第345行调用findColumns,其中c来自你的onLoadFinished方法,在那种情况下是'data',但是传递给findColumsn的mOriginalFrom是null,因为在SimpleCursorAdapter的初始化中你在第四个参数中传递null。您可以更好地阅读下面复制的SimpleCursorAdapter的构造函数:

 public SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) {
    super(context, layout, c, flags);
    mTo = to;
    mOriginalFrom = from;
    findColumns(c, from);
}

读取SimpleCursorAdapter的来源,mOriginalFrom被更改的唯一地方是调用方法changeCursorAndColumns。