当我尝试使用
从我的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
}
}
答案 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这将使您的生活更轻松。