【问题标题】:Android NullPointerException and GetDatabaseLockedAndroid NullPointerException 和 GetDatabaseLocked
【发布时间】:2014-04-15 22:33:38
【问题描述】:

我试图将特定列数据存储在一个方法中,并在另一个类 String [] 中调用该方法,其中微调器将访问该数组以显示列行供用户选择,然后将其存储在另一个数据库中。

我得到了 nulpointerexception,当我尝试打开()数据库时,数据库被锁定。对不起,听起来像一个完全的业余爱好者,对安卓来说相对较新。提前感谢您的帮助。

这是我在主类中调用 getInstance() 和 getCPnames() 时的代码

    String[] carParks = CarParkDb.getInstance().getCpnames();

这是我的数据库代码:

package com.example.parkangel;

import java.util.ArrayList;
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;

public class CarParkDb {


    public static final String KEY_ID = "_id";
    public static final String KEY_CPNAME = "cpname";
    public static final String KEY_COST = "cost";


    private static final String DATABASE_NAME = "CPDB";
    private static final String DATABASE_TABLE = "CPTable";
    private static final int DATABASE_VERSION = 1;

    private CPDbHelper cpdbHelper;

    private Context ourContext;
    private SQLiteDatabase ourDatabase;
    private static CarParkDb instance;


    private static class CPDbHelper extends SQLiteOpenHelper{

        public CPDbHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
            // TODO Auto-generated constructor stub
        }



@Override
        public void onCreate(SQLiteDatabase db) {
            // TODO Auto-generated method stub
            db.execSQL("CREATE TABLE " + DATABASE_TABLE + " (" +
                    KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                    KEY_CPNAME + " TEXT NOT NULL, " + KEY_COST + " TEXTNOT NULL);");

            db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values('1','LearningResource Center','2');");
            db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values ('2','ParkandRide','1');");
            db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values ('3','deHavilland Campus','2');");
            db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values('4','MultiStorey Building','2');");
            db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values('5','Reception','2');");

        }

        public void onOpen(final SQLiteDatabase db) {
            super.onOpen(db);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            // TODO Auto-generated method stub

            db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
            onCreate(db);
        }
    }

        public CarParkDb (final Context c)
        {
            this.cpdbHelper= new CPDbHelper(c);
            establishDb();
            //ourContext = c;
}
        public void establishDb()
        {
            if (this.ourDatabase == null)
            {
                this.ourDatabase = this.cpdbHelper.getWritableDatabase();
            }

        }

        public CarParkDb() {
            // TODO Auto-generated constructor stub
        }
        public CarParkDb open() throws SQLException
        {
            System.out.println ("running open");
            cpdbHelper = new CPDbHelper(ourContext);
            ourDatabase = cpdbHelper.getWritableDatabase();
            return this;
        }

        public void close()
        {
            ourDatabase.close();
        }

        /*public long createEntry(String cpname, String cost){
            ContentValues cv = new ContentValues();
            cv.put(KEY_CPNAME, cpname);
            cv.put(KEY_COST, cost);
            return ourDatabase.insert(DATABASE_TABLE, null, cv);
        }*/

        public String getData() {
            // TODO Auto-generated method stub
            //open();
            String[] columns = new String[] {KEY_ID, KEY_CPNAME, KEY_COST};
            Cursor  c = ourDatabase.query(DATABASE_TABLE, columns, null,null,null, null, null);
            String result = " ";

            int iRow = c.getColumnIndexOrThrow(KEY_ID);
            int iCpname = c.getColumnIndexOrThrow(KEY_CPNAME);
            int iCost = c.getColumnIndexOrThrow(KEY_COST);

            for(c.moveToFirst(); !c.isAfterLast(); c.moveToNext()){
                result = result + c.getString(iRow) + " " +c.getString(iCpname) + " " + c.getString(iCost) + " " + "\n";
                c.close();
                ourDatabase.close();
            }
            return result;
        }

        public static CarParkDb getInstance()
        {
            synchronized(CarParkDb.class)
        {
            if (instance == null)
            {
                instance = new CarParkDb();
            }   
            return instance;
        }
        }

    public String[] getCpnames()
        {
            //open();
            if (ourDatabase == null) System.out.println ("is null");
            Cursor c = null;

            ArrayList<String> list = new ArrayList<String>();
            ourDatabase = cpdbHelper.getReadableDatabase();
            //SQLiteDatabase db = cpdbHelper.getReadableDatabase();
            String query = "SELECT " + KEY_CPNAME + " FROM " + DATABASE_TABLE;



            {
            c = this.ourDatabase.rawQuery(query, null);
            int iCpname = c.getColumnIndexOrThrow(KEY_CPNAME);
            if (c.moveToFirst())
                {
                    do
                    {
                    list.add(c.getString(iCpname));;
                    }           
                    while (c.moveToNext());
                }
                if (c != null && !c.isClosed())
                {
                c.close();
                ourDatabase.close();
                }
                return list.toArray(new String[]{});
            }
        }

} 

**LogCat**

    03-12 01:32:39.759: E/AndroidRuntime(4176): Caused by:java.lang.NullPointerException
    03-12 01:32:39.759: E/AndroidRuntime(4176):     

    at com.example.parkangel.CarParkDb.getCpnames(CarParkDb.java:191)
    03-12 01:32:39.759: E/AndroidRuntime(4176):     

    at com.example.parkangel.BookTicket.<init>(BookTicket.java:22)
    03-12 01:32:39.759: E/AndroidRuntime(4176):     

    at java.lang.Class.newInstanceImpl(Native Method)
    03-12 01:32:39.759: E/AndroidRuntime(4176):     

    at java.lang.Class.newInstance(Class.java:1208)

【问题讨论】:

标签: java android sqlite singleton database-locking


【解决方案1】:

数据库没有被锁定。 “锁定”的 thinkg 只是一个名为 getDatabaseLocked() 的方法中的 NPE,它是由传递给 SQLiteOpenHelper 的构造函数中的 null Context 引起的,该构造函数以 getWritableDatabase()getReadableDatabase() 显示自身。

要修复getDatabaseLocked() 中的NPE,请确保open() 中的ourContext 不是null。到目前为止,您从未初始化过ourContext,它始终是null。取消注释构造函数中的 //ourContext = c; 并将其移至 establishDb() 上方,删除其他无参数构造函数并传入 Context,例如 Merlevede 所建议的。

您问题中的 NPE 堆栈跟踪是当您调用 getCpNames() 并注释掉 open() 并尝试在 null ourDatabase 对象引用上调用方法时。修复后取消注释那里的open()。堆栈跟踪还说您正在尝试在对象初始化阶段调用getCpNames(),例如初始化成员变量时。这可能还为时过早,例如,在onCreate() 之前,活动不能用作Context

您接下来会遇到的代码中的其他一些内容:

  • onCreate():+ KEY_COST + " TEXTNOT NULL) - 在TEXTNOT之间添加空格

  • getData():你正在关闭你正在访问游标的循环中的游标和数据库。在循环之后执行。代码不应编译,因为如果 moveToFirst() 返回 false,您不会从非 void 函数返回任何内容。

【讨论】:

  • 您好,谢谢您的回答。不幸的是,它对我不起作用。我收到以下错误以及通常的数据库锁定错误:03-12 12:31:41.879: E/AndroidRuntime(3110): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:256)
【解决方案2】:

尝试使用以下代码更新您的 getInstance() 代码:

public static CarParkDb getInstance(Context c) // <-- added context as parameter
{
    synchronized(CarParkDb.class)
    {
        if (instance == null)
        {
            instance = new CarParkDb(c); // <-- used context in constructor
        }   
        return instance;
    }
}

问题似乎是您使用的构造函数(对于CarParkDb)什么都不做。您有另一个构造函数,它以 Context 作为参数并初始化您稍后使用的一些对象。

【讨论】:

  • 您好,感谢您的快速答复。我还必须更改 String[] carParks=CarParkDb.getInstance().getCpnames();到 String[] carParks=CarParkDb.getInstance(null).getCpnames();我在 LogCat 中收到以下消息:03-12 02:13:58.269: E/AndroidRuntime(5957): Caused by: java.lang.NullPointerException 03-12 02:13:58.269: E/AndroidRuntime(5957): at android .database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224) 03-12 02:13:58.269: E/AndroidRuntime(5957): 在 android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)跨度>
  • 你不应该将null传递给getInstance()函数,你应该传递一个Context对象,如果你从一个Activity调用它,你可以使用this而不是null
  • 我从数据库类中调用它,所以不太确定要放什么。此外,我尝试了很多方法来阻止数据库被锁定,但似乎每一个微小的变化都会导致 nullpointerexception 或数据库被锁定。只是绕圈子:/
猜你喜欢
  • 2014-03-19
  • 1970-01-01
  • 1970-01-01
  • 2014-05-31
  • 2012-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多