【发布时间】:2016-11-20 09:16:22
【问题描述】:
背景: 我是 Android 新手,我在 assets 文件夹中有一个数据库,用户应该能够从操作栏中搜索该数据库。 我不会从代码本身创建该数据库,而是在第一次启动应用程序时创建一个空数据库,并将我的数据库复制到该空数据库。 现在,当我尝试搜索应用程序时,由于以下错误而崩溃。 我已经从link 复制/编辑了代码。
已尝试的解决方案
- 我在 stackoverflow.com 和 cmets 上查看了答案 上面链接中的部分。似乎大多数管理过的人 为了解决这个错误,在不同的地方关闭了数据库 代码(db.close)。我已经尝试按照评论发表结束声明 在我的代码中,但徒劳无功。
- 我知道提出的要点之一是永远不会对 db 的路径进行硬编码,因此我检查了该表是否存在!
- 卸载,清除缓存,更改数据库版本号。还是一样
错误:
java.lang.RuntimeException:无法启动活动 组件信息{com.amgad.hayy/com.amgad.hayy.SearchableActivity}: android.database.sqlite.SQLiteException:没有这样的表:地方(代码 1): , 编译时: SELECT type, name FROM places WHERE _id=?
错误代码:1 (SQLITE_ERROR) 原因:SQL(query) 错误或缺失 数据库。 (没有这样的表:places(代码1):,编译时:SELECT 类型、名称来自地点 WHERE _id=?)
完整的 LogCat
11-20 10:52:35.231 28023-28023/com.amgad.hayy E/AndroidRuntime: 致命异常: main 进程:com.amgad.hayy,PID:28023 java.lang.RuntimeException:无法启动活动 ComponentInfo{com.amgad.hayy/com.amgad.hayy.SearchableActivity}:android.database.sqlite.SQLiteException:没有这样的表:地点(代码 1):,编译时:SELECT类型,名称来自地点 WHERE _id=? ################################################# ############### 错误代码:1(SQLITE_ERROR) 原因:SQL(查询)错误或缺少数据库。 (没有这样的表:places (code 1): ,编译时:SELECT 类型,name FROM places WHERE _id=?) 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3319) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3415) 在 android.app.ActivityThread.access$1100(ActivityThread.java:229) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1821) 在 android.os.Handler.dispatchMessage(Handler.java:102) 在 android.os.Looper.loop(Looper.java:148) 在 android.app.ActivityThread.main(ActivityThread.java:7331) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120) 引起:android.database.sqlite.SQLiteException:没有这样的表: 地点(代码 1):,编译时:SELECT 类型,名称 FROM 地点 在哪里_id =? ################################################# ############### 错误代码:1(SQLITE_ERROR) 原因:SQL(查询)错误或缺少数据库。 (没有这样的表:places (code 1): ,编译时:SELECT 类型,名称 FROM 地点 WHERE _id=?) ################################################# ############### 在 android.database.sqlite.SQLiteConnection.nativePrepareStatement(本机 方法) 在 android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1000) 在 android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:565) 在 android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588) 在 android.database.sqlite.SQLiteProgram.(SQLiteProgram.java:59) 在 android.database.sqlite.SQLiteQuery.(SQLiteQuery.java:37) 在 android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44) 在 android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1476) 在 android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1323) 在 android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1194) 在 android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1362) 在 com.amgad.hayy.data.HayyDbHelper.getAllEmployeesDescription(HayyDbHelper.java:228) 在 com.amgad.hayy.SearchableActivity.showPlaceName(SearchableActivity.java:52) 在 com.amgad.hayy.SearchableActivity.onCreate(SearchableActivity.java:44) 在 android.app.Activity.performCreate(Activity.java:6904) 在 android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1136) 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3266) ... 9 更多
代码
公共类 HayyDbHelper 扩展 SQLiteOpenHelper
private static String DB_PATH = "/data/data/com.amgad.hayy/databases/"; static final String DB_NAME = "hayy.db"; private SQLiteDatabase myDataBase; private final Context myContext; private static final int DB_VERSION = 1; public static final String TABLE_NAME = "places"; public static final String COLUMN_PLACE_ID = "_id"; public static final String COLUMN_MONUMENT_NUMBER = "monument_number"; public static final String COLUMN_TYPE = "type"; public static final String COLUMN_NAME = "name"; public HayyDbHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); this.myContext = context; } public void createDb() throws IOException{ boolean dbExists = checkDb(); //SQLiteDatabase db_Read = null; if(dbExists){ //do nothing, db already exists }else{ //By calling this method an empty database will be created into the default system path //of the application so we are gonna be able to overwrite that database with our database. //db_Read = this.getReadableDatabase(); //db_Read.close(); this.getReadableDatabase(); try{ // this.close(); copyDb(); }catch(IOException e){ throw new Error("Error copying database"); } } //this.close(); } private boolean checkDb(){ File databasePath = myContext.getDatabasePath(DB_NAME); return databasePath.exists(); } private void copyDb() throws IOException{ //Open your local db as the input stream InputStream myInput = myContext.getAssets().open(DB_NAME); //Path to the just created empty db String outFileName = DB_PATH + DB_NAME; //Open the empty db as the output stream OutputStream myOutput = new FileOutputStream(outFileName); //transfer bytes from the inputfile to the outputfile byte[] buffer = new byte[1024]; int length; while ((length = myInput.read(buffer))>0){ myOutput.write(buffer, 0, length); } //Close the streams myOutput.flush(); myOutput.close(); myInput.close(); } public void openDb() throws SQLException { //Open the database String myPath = DB_PATH + DB_NAME; myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY); } @Override public synchronized void close() { if(myDataBase != null) myDataBase.close(); super.close(); } @Override public void onCreate(SQLiteDatabase db) { } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){ db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); onCreate(db); } public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) { onUpgrade(db, oldVersion, newVersion); } public ArrayList<String> getAllName() { SQLiteDatabase db = this.getReadableDatabase(); ArrayList<String> pNames = new ArrayList<String>(); Cursor cursor = db.query(TABLE_NAME, null, null, null, null, null, null); if (cursor != null && cursor.getCount() > 0) { cursor.moveToFirst(); do { String name = cursor.getString(cursor.getColumnIndex(COLUMN_NAME)); pNames.add(name); } while (cursor.moveToNext()); } cursor.close(); db.close(); return pNames; } public Cursor getAllEmployeesDescription(int id) { SQLiteDatabase db = this.getReadableDatabase(); String[] selections = {String.valueOf(id)}; String columns[] = {COLUMN_TYPE, COLUMN_NAME}; Cursor cursor = db.query(TABLE_NAME, columns, COLUMN_PLACE_ID + "=?", selections, null, null, null); //db.close(); return cursor; }
主要方法
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myDatabaseHelper = new HayyDbHelper(MainActivity.this); try { myDatabaseHelper.createDb(); } catch (IOException ioe) { throw new Error("Unable to create database"); } try { myDatabaseHelper.openDb(); }catch(SQLException sqle){ throw sqle; } }
【问题讨论】:
-
为什么是mysql标签?只需使用SQLiteAssetHelper。
-
@CL.tags 已编辑。正在考虑您的建议,谢谢。
标签: java android database sqlite