【问题标题】:SQLite and Android, moving to next row in database, retrieving and then displaying the resultsSQLite 和 Android,移动到数据库中的下一行,检索然后显示结果
【发布时间】:2013-03-10 21:23:11
【问题描述】:

我正在尝试获取在使用 SQLite 数据库的 Android 上运行的电话簿。

我正在努力解决的问题是,当我单击下一个按钮时,我希望显示数据库中的下一行数据。但是,当我运行应用程序时,我不断收到此错误

03-10 12:05:22.455:E/AndroidRuntime(772):致命异常:主要 03-10 12:05:22.455: E/AndroidRuntime(772): java.lang.RuntimeException: 无法实例化活动 ComponentInfo{com.example.adressbooktake2/com.example.adressbooktake2.MainActivity}: java.lang.NullPointerException

这是我正在使用的代码,

MainActivity.Java

public class MainActivity extends Activity {  

    DBAdaptor db = new DBAdaptor(this);
    int count = 1;
    Cursor cursor = db.getallRecord();



protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);         
        DisplayRecord(cursor);

    }

public void Nextdata (View view){

        if (cursor.moveToNext())
        { 
            DisplayRecord(cursor);
        }           

    }

    public void Previousdata (View view){

        if (cursor.moveToPrevious())
        { 
            DisplayRecord(cursor);
        }
    }

public void DisplayRecord(Cursor c) {

        EditText nameTxt = (EditText)findViewById(R.id.Name);
        EditText phoneTxt = (EditText)findViewById(R.id.Phone);
        EditText emailTxt = (EditText)findViewById(R.id.Email);     
        nameTxt.setText(c.getString(1));
        phoneTxt.setText(c.getString(2));
        emailTxt.setText(c.getString(3));//
    }

DBAdaptor.Java

    package com.example.adressbooktake2;

import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class DBAdaptor {
    public static final String KEY_ROWID = "id";
    public static final String KEY_NAME = "name";
    public static final String KEY_PHONENUMBER = "phone";
    public static final String KEY_EMAIL = "email";
    private static final String TAG = "DBAdaptor";

    public static final String DATABASE_NAME = "AddressBookDataBase1";
    public static final String DATABASE_TABLE = "AddressBook";
    public static final int DATABASE_VERSION = 1;

    public static final String DATABASE_CREATE = "create table if not exists AddressBook (id integer primary key autoincrement, "
            + "name VARCHAR, phone VARCHAR, email VARCHAR);";


    private final Context context;

    private DatabaseHelper DBHelper;
    private SQLiteDatabase db;

    public DBAdaptor(Context ctx)
    {
    this.context = ctx;
    DBHelper = new DatabaseHelper(context);
    }

    private static class DatabaseHelper extends SQLiteOpenHelper
    {
        DatabaseHelper(Context context)
        {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) 
        {
            try 
            {
                db.execSQL(DATABASE_CREATE);
            } 
                catch (SQLException e) 
            {
                    e.printStackTrace();
            }
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
        {
            Log.w(TAG, "Upgrading database from version " + oldVersion + " to" + newVersion +
                    ", which will destroy all old data");
            db.execSQL("Drop TABLE IF EXISTS AddressBook");
            onCreate(db);

        }       
    }

    //--counts rows in database--
    public int rowCounter()
    {
        Cursor mCount= db.rawQuery("select count(*) from AddressBook where id=" + KEY_ROWID, null);
        mCount.moveToFirst();
        int rowCount= mCount.getInt(0);
        return rowCount;
    }




    //--opens the database---
    public DBAdaptor open() throws SQLException
    {
        db = DBHelper.getWritableDatabase(); //Line 88
        return this;
    }

    //--close the dabatabase
    public void close()
    {
        DBHelper.close();
    }

    //--insert a record into database--
    public long insertRecord(String name, String email, String phone)
    {
        ContentValues initialValues = new ContentValues();
        initialValues.put(KEY_NAME, name);
        initialValues.put(KEY_EMAIL, email);
        initialValues.put(KEY_PHONENUMBER, phone);
        return db.insert(DATABASE_TABLE, null, initialValues);
    }

    //--deletes a record
    public void deleteRecord(long rowId)
    {
        db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null);


    }

    //--retrieves a particular record--
    public Cursor getRecord(long rowId) throws SQLException
    {
        Cursor mCursor = 
                db.query(true, DATABASE_TABLE, new String[] {KEY_ROWID, KEY_NAME,
                        KEY_EMAIL, KEY_PHONENUMBER}, KEY_ROWID + "=" + rowId, null, null, null, null, null);
        if (mCursor !=null) {
            mCursor.moveToFirst();
        }
        return mCursor;
    }       

    //--Retrieves all data--


    public Cursor getallRecord() throws SQLException
    {
        {

            Cursor gaCursor = db.rawQuery("SELECT* FROM " + DATABASE_TABLE, null);                  
            if (gaCursor !=null) 
            {
                gaCursor.moveToFirst();
            }

            return gaCursor;
        }
    }

}

如果您能看出我哪里出错了,我们将不胜感激。

异常的完整堆栈跟踪是(2),

03-10 13:07:39.579:E/AndroidRuntime(770):致命异常:主 03-10 13:07:39.579:E/AndroidRuntime(770):java.lang.RuntimeException: 无法实例化活动 组件信息{com.example.adressbooktake2/com.example.adressbooktake2.MainActivity}: java.lang.NullPointerException 03-10 13:07:39.579: E/AndroidRuntime(770):在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2106) 03-10 13:07:39.579: E/AndroidRuntime(770): 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230) 03-10 13:07:39.579: E/AndroidRuntime(770): 在 android.app.ActivityThread.access$600(ActivityThread.java:141) 03-10 13:07:39.579:E/AndroidRuntime(770):在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234) 03-10 13:07:39.579: E/AndroidRuntime(770): 在 android.os.Handler.dispatchMessage(Handler.java:99) 03-10 13:07:39.579:E/AndroidRuntime(770):在 android.os.Looper.loop(Looper.java:137) 03-10 13:07:39.579: E/AndroidRuntime(770):在 android.app.ActivityThread.main(ActivityThread.java:5039) 03-10 13:07:39.579:E/AndroidRuntime(770):在 java.lang.reflect.Method.invokeNative(Native Method) 03-10 13:07:39.579:E/AndroidRuntime(770):在 java.lang.reflect.Method.invoke(Method.java:511) 03-10 13:07:39.579: E/AndroidRuntime(770):在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 03-10 13:07:39.579: E/AndroidRuntime(770): 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 03-10 13:07:39.579:E/AndroidRuntime(770):在 dalvik.system.NativeStart.main(Native Method) 03-10 13:07:39.579: E/AndroidRuntime(770):引起:java.lang.NullPointerException 03-10 13:07:39.579:E/AndroidRuntime(770):在 android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:229) 03-10 13:07:39.579: E/AndroidRuntime(770): 在 android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224) 03-10 13:07:39.579: E/AndroidRuntime(770): 在 android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164) 03-10 13:07:39.579: E/AndroidRuntime(770): 在 com.example.adressbooktake2.DBAdaptor.open(DBAdaptor.java:88) 03-10 13:07:39.579:E/AndroidRuntime(770):在 com.example.adressbooktake2.MainActivity.(MainActivity.java:20) 03-10 13:07:39.579: E/AndroidRuntime(770): 在 java.lang.Class.newInstanceImpl(本机方法)03-10 13:07:39.579: E/AndroidRuntime(770):在 java.lang.Class.newInstance(Class.java:1319) 03-10 13:07:39.579: E/AndroidRuntime(770):在 android.app.Instrumentation.newActivity(Instrumentation.java:1054) 03-10 13:07:39.579: E/AndroidRuntime(770): 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2097)

【问题讨论】:

  • 对于这样的问题,您应该在代码示例中用注释指出异常发生的行,因为我们不能按行号。还要确定该语句中涉及的各种变量/子表达式的值是什么。 (也就是说,等于null。)这对您来说使用日志记录或调试器比通过目测代码更容易。

标签: java android database sqlite


【解决方案1】:
    if (gaCursor !=null) 
    {
        gaCursor.moveToFirst();
    }
    else
    {
        gaCursor.close();
    }

如果gaCursor 为空,将抛出 NPE。

如果为 null,则不能(也不需要)关闭它。

只需删除 else 部分。

您还需要更改DisplayRecord 函数。在调用c.toString()之前检查c是否为空。

if (c!= null){
    nameTxt.setText(c.getString(1));
    phoneTxt.setText(c.getString(2));
    emailTxt.setText(c.getString(3));//
}

另外,您不要在 DBAdaptor.Java 文件中实例化 db,使用 open() 或在 onCreate 中添加 this.db = db(使用 open 更好)

【讨论】:

  • 我删了,还是一样的异常:(
  • 又是在同一个地方吗?比较两个堆栈跟踪。
  • NPE 在哪一行被抛出?
  • getallRecord 行是上面的第二个代码窗口。目的是让游标获取所有数据库数据。
  • 即使我删除了 ELSE 部分,NPE 仍然在同一个地方。
【解决方案2】:

这通常是在调用onCreate() 之前执行逻辑的错误的来源。在你的情况下:

DBAdaptor db = new DBAdaptor(this);
int count = 1;
Cursor cursor = db.getallRecord();

尽量只声明变量并在onCreate中初始化它们:

public class MainActivity extends Activity {  

    DBAdaptor db;
    int count = 1;
    Cursor cursor;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);         

        db = new DBAdaptor(this);
        cursor = db.getallRecord();
        DisplayRecord(cursor);
    }
    [...]
}

也可以看看this SO question

【讨论】:

    【解决方案3】:

    移动这个

    EditText nameTxt = (EditText)findViewById(R.id.Name);
            EditText phoneTxt = (EditText)findViewById(R.id.Phone);
            EditText emailTxt = (EditText)findViewById(R.id.Email);   
    

    喜欢这个

    setContentView(R.layout.activity_main);
        EditText nameTxt = (EditText)findViewById(R.id.Name);
                EditText phoneTxt = (EditText)findViewById(R.id.Phone);
                EditText emailTxt = (EditText)findViewById(R.id.Email);            
            DisplayRecord(cursor);
    

    【讨论】:

      【解决方案4】:

      似乎是getallRecord()返回的Cursor对象为空... 而空指针异常指的是DisplayRecord()中访问的空Cursor对象...

      在显示记录之前执行如下检查:

      if(c != null)
          //Display Records
      else
          Log.e(TAG, "Cursor is Null");
      

      此外,从数据库中检索联系人的方式似乎也不是正确的... 创建了某些ContentProvider 以使数据库中的数据可供应用程序使用...This 可能会有所帮助...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-19
        • 2021-10-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多