我正在尝试创建一个应用程序,我需要使用从SQLite数据库中检索的数据生成ListView。
但是,一旦启动执行上述任务的活动,应用程序就会崩溃。
这是活动代码:
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class DisplayTasks extends ListActivity implements LoaderManager.LoaderCallbacks<Cursor>{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SimpleCursorAdapter adapter;
String fromColumns[] = {TaskEntryDetails.TASK_SUMMARY};
int toViews[] = {R.id.textView1};
adapter = new SimpleCursorAdapter(this, R.layout.list_item, null, fromColumns, toViews, 0);
setListAdapter(adapter);
// Prepare the loader. Either re-connect with an existing one, or start a new one.
getLoaderManager().initLoader(0, null, this);
}
private SQLiteCursorLoader loader;
private SimpleCursorAdapter adapter;
private DbHelper dbHelper;
private SQLiteOpenHelper db=null;
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
//New
TaskEntry taskentry = new TaskEntry(DisplayTasks.this);
dbHelper=taskentry.DbHelpermethod();
db = dbHelper;
String rawQuery = "SELECT " + TaskEntryDetails._ID + " , " + TaskEntryDetails.TASK_SUMMARY + " FROM " + TaskEntryDetails.TABLE_NAME;
loader = new SQLiteCursorLoader(this, db, rawQuery, null);
return(loader);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
adapter.changeCursor(cursor);
}
@Override
public void onLoaderReset(Loader<Cursor> arg0) {
adapter.changeCursor(null);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_display_tasks, menu);
return true;
}
}
logcat报告包含:
03-07 19:38:12.311: E/AndroidRuntime(32626): Caused by: java.lang.NullPointerException
03-07 19:38:12.311: E/AndroidRuntime(32626): at com.commonsware.cwac.loaderex.SQLiteCursorLoader.buildCursor(SQLiteCursorLoader.java:54)
03-07 19:38:12.311: E/AndroidRuntime(32626): at com.commonsware.cwac.loaderex.AbstractCursorLoader.loadInBackground(AbstractCursorLoader.java:41)
03-07 19:38:12.311: E/AndroidRuntime(32626): at com.commonsware.cwac.loaderex.AbstractCursorLoader.loadInBackground(AbstractCursorLoader.java:1)
03-07 19:38:12.311: E/AndroidRuntime(32626): at android.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:301)
03-07 19:38:12.311: E/AndroidRuntime(32626): at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:68)
03-07 19:38:12.311: E/AndroidRuntime(32626): at android.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:56)
03-07 19:38:12.311: E/AndroidRuntime(32626): at android.os.AsyncTask$2.call(AsyncTask.java:287)
03-07 19:38:12.311: E/AndroidRuntime(32626): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
03-07 19:38:12.311: E/AndroidRuntime(32626): ... 3 more
03-07 19:38:12.321: W/DropBoxManagerService(481): Dropping: data_app_crash (1407 > 0 bytes)
03-07 19:38:12.331: W/ActivityManager(481): Force finishing activity com.example.theapp/.DisplayTasks
03-07 19:38:12.361: W/ActivityManager(481): Force finishing activity com.example.theapp/.MainActivity
03-07 19:38:12.481: I/ActivityManager(481): Displayed com.example.theapp/.DisplayTasks: +219ms
03-07 19:38:14.381: I/Process(32626): Sending signal. PID: 32626 SIG: 9
03-07 19:38:14.391: I/ActivityManager(481): Process com.example.theapp (pid 32626) has died.
03-07 19:38:14.411: W/InputMethodManagerService(481): Got RemoteException sending setActive(false) notification to pid 32626 uid 10083
这是TaskEntry.java的代码
public static final String TAG = "TaskEntry";
private DbHelper dbHelper;
public TaskEntry(Context context){
dbHelper = new DbHelper(context);
}
public DbHelper DbHelpermethod() {
return this.dbHelper();
}
// Inserting into Database
public void insertIntoDb(String summary) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
// Create a new map of values, where column names are the keys
ContentValues values = new ContentValues();
values.put(TaskEntryDetails.TASK_SUMMARY, summary);
@SuppressWarnings("unused")
long newRowId;
newRowId = db.insert(TaskEntryDetails.TABLE_NAME, TaskEntryDetails._ID, values);
}
和DbHelper.java:
public class DbHelper extends SQLiteOpenHelper {
public static final String TAG = "TaskEntry";
private static Context context;
public DbHelper(Context context) {
super(context, TaskEntryDetails.DB_NAME, null, TaskEntryDetails.DB_VERSION);
this.context=context;
}
@Override
public void onCreate(SQLiteDatabase db) {
String sql = String.format("CREATE TABLE %s" + "(%s INT PRIMARY KEY, %s TEXT)", TaskEntryDetails.TABLE_NAME, TaskEntryDetails._ID,TaskEntryDetails.TASK_SUMMARY);
Log.d(TAG, "Created database by name - " + TaskEntryDetails.DB_NAME);
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP IF EXISTS " + TaskEntryDetails.TABLE_NAME);
onCreate(db);
}
TaskEntryDetails.java:
public class TaskEntryDetails implements BaseColumns {
public static final String DB_NAME = "tasks_list.db";
public static final int DB_VERSION = 1;
public static final String TABLE_NAME = "tasks_list";
public static final String TASK_SUMMARY = "task_details";
}
我目前正在使用开源库'CWAC-LoaderEX'来获取SQLite数据库中数据的CursorLoader。
我已经成功检索并将同一数据库中的数据显示到ScrollView中,所以希望问题不能出现在数据库中。
编辑1:
现在代码似乎崩溃了另一条消息..
03-08 20:37:10.031: D/libEGL(9969): loaded /system/lib/egl/libEGL_tegra.so
03-08 20:37:10.071: D/libEGL(9969): loaded /system/lib/egl/libGLESv1_CM_tegra.so
03-08 20:37:10.091: D/libEGL(9969): loaded /system/lib/egl/libGLESv2_tegra.so
03-08 20:37:10.141: D/OpenGLRenderer(9969): Enabling debug mode 0
03-08 20:37:12.411: D/AndroidRuntime(9969): Shutting down VM
03-08 20:37:12.411: W/dalvikvm(9969): threadid=1: thread exiting with uncaught exception (group=0x40c28930)
03-08 20:37:12.421: E/AndroidRuntime(9969): FATAL EXCEPTION: main
03-08 20:37:12.421: E/AndroidRuntime(9969): java.lang.NullPointerException
03-08 20:37:12.421: E/AndroidRuntime(9969): at com.example.theapp.DisplayTasks.onLoadFinished(DisplayTasks.java:83)
03-08 20:37:12.421: E/AndroidRuntime(9969): at com.example.theapp.DisplayTasks.onLoadFinished(DisplayTasks.java:1)
03-08 20:37:12.421: E/AndroidRuntime(9969): at android.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:483)
03-08 20:37:12.421: E/AndroidRuntime(9969): at android.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:451)
03-08 20:37:12.421: E/AndroidRuntime(9969): at android.content.Loader.deliverResult(Loader.java:143)
03-08 20:37:12.421: E/AndroidRuntime(9969): at com.commonsware.cwac.loaderex.AbstractCursorLoader.deliverResult(AbstractCursorLoader.java:71)
03-08 20:37:12.421: E/AndroidRuntime(9969): at com.commonsware.cwac.loaderex.AbstractCursorLoader.deliverResult(AbstractCursorLoader.java:1)
答案 0 :(得分:1)
03-07 19:38:12.311: E/AndroidRuntime(32626): Caused by: java.lang.NullPointerException
03-07 19:38:12.311: E/AndroidRuntime(32626): at com.commonsware.cwac.loaderex.SQLiteCursorLoader.buildCursor(SQLiteCursorLoader.java:54)
假设您正在使用最新代码,该行是return
语句:
@Override
protected Cursor buildCursor() {
return(db.getReadableDatabase().rawQuery(rawQuery, args));
}
这意味着db
为null
(因为您将null
SQLiteOpenHelper
传递给SQLiteCursorLoader
构造函数)或因为db.getReadableDatabase()
是null
(不应该发生)。
而且,由于我无法在上面的代码中看到您在哪里创建SQLiteOpenHelper
对象,这可能是您遇到困难的根源。
请记住,当使用开源库时,它们是开源,这意味着您可以阅读与它们相关的代码,以帮助您跟踪这些问题。
答案 1 :(得分:0)
问题最初是正确初始化数据库。应该这样做:
TaskEntry类(在TaskEntry.java中)
public class TaskEntry {
public static final String TAG = "TaskEntry";
private DbHelper dbHelper;
public TaskEntry(Context context){
dbHelper = new DbHelper(context);
}
public DbHelper DbHelpermethod() {
return this.dbHelper;
}
...}
此外,LoaderManager未正确实现..
在onCreateLoader(相当正常)之后..初始化了一个游标,它没有被传递到onLoadFinished和onLoaderReset调用。它们在这里接收旧的适配器,它用'null'作为游标值进行初始化。 价:
adapter = new SimpleCursorAdapter(this, R.layout.list_item, null, fromColumns, toViews, 0);
这可以通过替换:
来解决adapter.changeCursor(cursor);
在onLoadFinished和
adapter.changeCursor(null);
在DisplayTasks.java活动的onLoaderReset中:
((SimpleCursorAdapter)this.getListAdapter()).changeCursor(cursor);
和..
((SimpleCursorAdapter)this.getListAdapter()).changeCursor(null);
repectively ..