我查看了其他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)
答案 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。