【问题标题】:Android application crashes on starting an Activity with message 'FATAL EXCEPTION: Async #3'Android 应用程序在启动 Activity 时崩溃并显示消息“FATAL EXCEPTION: Async #3”
【发布时间】:2013-03-07 16:03:27
【问题描述】:

我正在尝试制作一个应用程序,我需要使用从 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)

【问题讨论】:

  • 你为什么评论//dbHelper = new TaskEntry.DbHelper(); 行?您收到错误是因为 dbdbHelper 实例是 null
  • @ρяσѕρєяK 我实际上尝试过这样做,但 eclipse 拒绝我这样做。它说'没有 TaskEntry 类型的封闭实例是可访问的。必须使用 TaskEntry 类型的封闭实例来限定分配。'
  • 如果TaskEntry 是类并且DbHelper() 是非静态方法,则使用dbHelper=new TaskEntry().DbHelper() 而不是dbHelper = new TaskEntry.DbHelper();,如果DbHelper() 是静态方法,则使用dbHelper=TaskEntry.DbHelper()
  • @ρяσѕρєяK 看起来我无法弄清楚这种方式。所以我在这里发布 TaskEntry.java 的代码:link
  • ok 显示TaskEntry.java类代码

标签: android android-listview android-activity android-cursorloader


【解决方案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));
  }

这意味着dbnull(因为您将null SQLiteOpenHelper 传递给SQLiteCursorLoader 构造函数)或者因为db.getReadableDatabase()null(这不应该发生)。

而且,由于我看不到您在上面的代码中创建 SQLiteOpenHelper 对象的位置,这很可能是您遇到困难的根源。

请记住,在使用开源库时,它们是开源,这意味着您可以阅读与它们相关的代码,以帮助您追踪此类问题。

【讨论】:

  • 这里好像无法初始化数据库助手对象。我已经在帖子中添加了处理它的文件的代码。另外,告诉我在这里使用 SQLiteOpenHelper 是否可以。
  • @AdityaBhardwaj:“我似乎无法在此处初始化数据库助手对象”——是的,您可以,例如在您的活动中的onCreate()。 “我已经在帖子中添加了处理它的文件的代码”——不,你没有,因为似乎创建一个的唯一代码已被注释掉,因此无法执行。 “另外,告诉我在这里使用 SQLiteOpenHelper 是否可以”——你应该在某个地方保留你的 SQLiteOpenHelper,因为你以后可能会需要它。
  • 谢谢..我发现了我的问题..:-) 虽然我的名声不允许我投票支持你的答案..
【解决方案2】:

问题最初在于正确初始化数据库。应该这样做:

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

分别..

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-07
    • 2022-01-06
    • 2014-09-06
    • 1970-01-01
    • 1970-01-01
    • 2020-12-02
    • 1970-01-01
    • 2021-02-26
    相关资源
    最近更新 更多