我尝试获取SQLite数据时的StringIndexOutOfBoundsException

时间:2012-12-10 17:08:22

标签: android sqlite android-sqlite indexoutofboundsexception

当我尝试使用

从我的Activity中的数据库SQLite获取数据时
DataBaseAdapterCars mDbHelper = new DataBaseAdapterCars(this);
        mDbHelper.createDatabase();
        mDbHelper.open();

        Car[] carsList= mDbHelper.getDataDBCarsArray(uso, eta,
        category, class);

我收到此错误

12-10 17:14:47.069: E/AndroidRuntime(17936): FATAL EXCEPTION: main
12-10 17:14:47.069: E/AndroidRuntime(17936): java.lang.StringIndexOutOfBoundsException
12-10 17:14:47.069: E/AndroidRuntime(17936):    at android.app.ContextImpl.validateFilePath(ContextImpl.java:1649)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:555)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:118)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:187)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at com.my.app.db.DataBaseHelper.createDataBase(DataBaseHelper.java:36)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at com.my.app.db.DataBaseAdapterCars.createDatabase(DataBaseAdapterCars.java:42)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at com.my.app.Cars.initializeData(Cars.java:111)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at com.my.app.Cars$MyAsync$1.run(Cars.java:156)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at android.os.Handler.handleCallback(Handler.java:587)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at android.os.Handler.dispatchMessage(Handler.java:92)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at android.os.Looper.loop(Looper.java:130)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at android.app.ActivityThread.main(ActivityThread.java:3687)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at java.lang.reflect.Method.invokeNative(Native Method)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at java.lang.reflect.Method.invoke(Method.java:507)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
12-10 17:14:47.069: E/AndroidRuntime(17936):    at dalvik.system.NativeStart.main(Native Method)

我的 DataBaseAdapterCars 类是

public class DataBaseAdapterCars {

    protected static final String TAG = "DataAdapter";

    private final Context mContext;
    private SQLiteDatabase mDb;
    private DataBaseHelper mDbHelper;
    static String currentDBName;

    String language;

    public DataBaseAdapterCars(Context context) {
        this.mContext = context;
        currentDBName = "CarInfo";
        mDbHelper = new DataBaseHelper(mContext, currentDBName);
        String lang = Locale.getDefault().getLanguage();
        if (lang.equals("es_ES")) {
            language = "ES";
        } else {
            language = "EN";
        }
    }

    public DataBaseAdapterCars createDatabase() throws SQLException {
        try {
            mDbHelper.createDataBase();
        } catch (IOException mIOException) {
            Log.e(TAG, mIOException.toString() + "  UnableToCreateDatabase");
            throw new Error("UnableToCreateDatabase");
        }
        return this;
    }

    public DataBaseAdapterCars open() throws SQLException {
        try {
            mDbHelper.openDataBase();
            mDbHelper.close();
            mDb = mDbHelper.getReadableDatabase();
        } catch (SQLException mSQLException) {
            Log.e(TAG, "open >>" + mSQLException.toString());
            throw mSQLException;
        }
        return this;
    }

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

    public Cursor getData(String uso, String eta, String category,
            String class) {
        try {
            Cursor c;
            if (class.equals(null) && category.equals(null)) {
                c = mDb.rawQuery("SELECT * FROM dbtable WHERE Uso LIKE \""
                        + uso + "\" AND Eta LIKE \"" + eta
                        + "\" AND Language LIKE \"" + language
                        + "\" order by Name asc", null);
            } else if (class.equals(null)) {
                c = mDb.rawQuery("SELECT * FROM dbtable WHERE Uso LIKE \""
                        + uso + "\" AND Eta LIKE \"" + eta
                        + "\" AND Tipo LIKE \"" + category
                        + "\" AND Language LIKE \"" + language
                        + "\" order by Name asc", null);
            } else if (category.equals(null)) {
                c = mDb.rawQuery("SELECT * FROM dbtable WHERE Uso LIKE \""
                        + uso + "\" AND Eta LIKE \"" + eta
                        + "\" AND Certification LIKE \"" + class
                        + "\" AND Language LIKE \"" + language
                        + "\" order by Name asc", null);
            } else {
                c = mDb.rawQuery("SELECT * FROM dbtable WHERE Uso LIKE \""
                        + uso + "\" AND Eta LIKE \"" + eta
                        + "\" AND Tipo LIKE \"" + category
                        + "\" AND Certification LIKE \"" + class
                        + "\" AND Language LIKE \"" + language
                        + "\" order by Name asc", null);
            }
            if (c != null) {
                c.moveToNext();
            }
            return c;
        } catch (SQLException mSQLException) {
            Log.e(TAG, "getDataCar >>" + mSQLException.toString());
            throw mSQLException;
        }

    }

    public Car[] getDataDBCarsArray(String uso, String eta,
            String category, String class) {
        ArrayList<Car> list = new ArrayList<Car>();
        Cursor c = getData(uso, eta, category, class);
        try {
            if (c.moveToFirst()) {
                do {
                    Car n = new Car(c.getString(0), c.getString(1),
                            c.getString(2), c.getString(3), c.getString(4),
                            c.getString(5), c.getString(6), c.getString(7),
                            c.getString(8), c.getString(9), c.getString(10),
                            c.getString(11), c.getString(12), c.getString(13));
                    list.add(n);
                } while (c.moveToNext());
            }
        } catch (SQLiteException e) {
            Log.d("SQL Error", e.getMessage());
            return null;
        } finally {
            c.close();
            mDb.close();
        }

        Car[] listArray = list.toArray(new Car[list.size()]);
        return listArray;
    }


}

DB表有14列,Object Car有14个String参数。

有什么问题?

DataBaseHelper类是

public class DataBaseHelper extends SQLiteOpenHelper {
    private static String TAG = "DataBaseHelper"; // Tag just for the LogCat
                                                    // window
    // destination path (location) of our database on device
    private static String DB_PATH = "";
    private static String DB_NAME = "";// Database name
    private SQLiteDatabase mDataBase;
    private final Context mContext;

    public DataBaseHelper(Context context, String nomeDB) {
        super(context, DB_NAME, null, 1);// 1? its Database Version
        DB_NAME = nomeDB;
        DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
        this.mContext = context;
    }

    public void createDataBase() throws IOException {
        // If database not exists copy it from the assets

        boolean mDataBaseExist = checkDataBase();
        if (!mDataBaseExist) {
            this.getReadableDatabase();
            this.close();
            try {
                // Copia il database dalla cartella assests
                copyDataBase();
                Log.e(TAG, "createDatabase database created");
            } catch (IOException mIOException) {
                throw new Error("ErrorCopyingDataBase");
            }
        }
    }

    // Controlla Che il database esista
    private boolean checkDataBase() {
        File dbFile = new File(DB_PATH + DB_NAME);
        // Log.v("dbFile", dbFile + "   "+ dbFile.exists());
        return dbFile.exists();
    }

    // Copia il database dalla cartella assests
    private void copyDataBase() throws IOException {
        InputStream mInput = mContext.getAssets().open(DB_NAME);
        String outFileName = DB_PATH + DB_NAME;
        OutputStream mOutput = new FileOutputStream(outFileName);
        byte[] mBuffer = new byte[1024];
        int mLength;
        while ((mLength = mInput.read(mBuffer)) > 0) {
            mOutput.write(mBuffer, 0, mLength);
        }
        mOutput.flush();
        mOutput.close();
        mInput.close();
    }

    // Apre il database, cosi da poter eseguire le query
    public boolean openDataBase() throws SQLException {
        String mPath = DB_PATH + DB_NAME;
        // Log.v("mPath", mPath);
        mDataBase = SQLiteDatabase.openDatabase(mPath, null,
                SQLiteDatabase.CREATE_IF_NECESSARY);
        // mDataBase = SQLiteDatabase.openDatabase(mPath, null,
        // SQLiteDatabase.NO_LOCALIZED_COLLATORS);
        return mDataBase != null;
    }

    @Override
    public synchronized void close() {
        if (mDataBase != null)
            mDataBase.close();
        super.close();
    }

    @Override
    public void onCreate(SQLiteDatabase arg0) {
        // TODO Auto-generated method stub

    }

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

    }

}

1 个答案:

答案 0 :(得分:6)

异常来自您实例化DataBaseHelper类的方式,最确切地说,来自它的构造函数:

//...
private static String DB_NAME = "";// Database name
    private SQLiteDatabase mDataBase;
    private final Context mContext;

    public DataBaseHelper(Context context, String nomeDB) {
        super(context, DB_NAME, null, 1);// 1? its Database Version
        DB_NAME = nomeDB;
//...

正如您所看到的那样,当您调用超级构造函数时,您会传递DB_NAME,这是一个空的String。在某些时候,您可以调用createDatabase()类的DataBaseHelper数据库,在其中调用:this.getReadableDatabase();。这将触发一些关于数据库的初始化,该初始化将因该异常而失败,因为您传递一个空字符串作为数据库名称。

即便如此,您的代码仍然很混乱,使用SQliteOpenHelper并从资产中复制数据库。如果您计划将数据库与您的应用程序捆绑在一起(在资产中),那么您可能需要考虑this library这将使您的生活更轻松。