首次运行时无法加载sqlite数据库

时间:2017-11-23 07:15:46

标签: android sqlite android-layout android-sqlite

我在安装时创建了一个应用程序并在第一次启动它时会自动关闭,但是当它在工作正常后打开它时。如果我清除应用程序的数据,它也会第一次关闭。它显示android.database.sqlite.SQLiteCantOpenDatabaseException:未知错误(代码14):无法打开数据库 任何人都可以帮助我的日志

11-22 23:14:56.175 13193-13193/? I/art: Late-enabling -Xcheck:jni
11-22 23:14:56.195 13193-13193/? D/TidaProvider: TidaProvider()
11-22 23:14:56.285 13193-13193/com.elytelabs.myapplication W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
11-22 23:14:56.455 13193-13193/com.elytelabs.myapplication E/SQLiteLog: (14) cannot open file at line 30052 of [b3bb660af9]
11-22 23:14:56.455 13193-13193/com.elytelabs.myapplication E/SQLiteLog: (14) os_unix.c:30052: (2) open(/data/data/com.elytelabs.myapplication/databases/dictionary.db) - 
11-22 23:14:56.455 13193-13193/com.elytelabs.myapplication E/SQLiteDatabase: Failed to open database '/data/data/com.elytelabs.myapplication/databases/dictionary.db'.
                                                                             android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
                                                                                 at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
                                                                                 at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:209)
                                                                                 at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:193)
                                                                                 at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:463)
                                                                                 at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:185)
                                                                                 at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:177)
                                                                                 at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:806)
                                                                                 at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:791)
                                                                                 at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:694)
                                                                                 at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:669)
                                                                                 at com.elytelabs.myapplication.DatabaseHelper.checkDataBase(DatabaseHelper.java:85)
                                                                                 at com.elytelabs.myapplication.DatabaseHelper.createDataBase(DatabaseHelper.java:50)
                                                                                 at com.elytelabs.myapplication.MainActivity.fetchData(MainActivity.java:129)
                                                                                 at com.elytelabs.myapplication.MainActivity.onCreate(MainActivity.java:82)
                                                                                 at android.app.Activity.performCreate(Activity.java:6039)
                                                                                 at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
                                                                                 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2295)
                                                                                 at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2404)
                                                                                 at android.app.ActivityThread.access$900(ActivityThread.java:154)
                                                                                 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1315)
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                 at android.os.Looper.loop(Looper.java:135)
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:5296)
                                                                                 at java.lang.reflect.Method.invoke(Native Method)
                                                                                 at java.lang.reflect.Method.invoke(Method.java:372)
                                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:707)
11-22 23:14:56.525 13193-13193/com.elytelabs.myapplication E/SQLiteLog: (1) no such table: Dictionary1
11-22 23:14:56.525 13193-13193/com.elytelabs.myapplication D/AndroidRuntime: Shutting down VM
11-22 23:14:56.525 13193-13193/com.elytelabs.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
                                                                             Process: com.elytelabs.myapplication, PID: 13193
                                                                             java.lang.RuntimeException: Unable to start activity ComponentInfo{com.elytelabs.myapplication/com.elytelabs.myapplication.MainActivity}: android.database.sqlite.SQLiteException: no such table: Dictionary1 (code 1): , while compiling: SELECT * FROM Dictionary1
                                                                                 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2342)
                                                                                 at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2404)
                                                                                 at android.app.ActivityThread.access$900(ActivityThread.java:154)
                                                                                 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1315)
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                 at android.os.Looper.loop(Looper.java:135)
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:5296)
                                                                                 at java.lang.reflect.Method.invoke(Native Method)
                                                                                 at java.lang.reflect.Method.invoke(Method.java:372)
                                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:707)
                                                                              Caused by: android.database.sqlite.SQLiteException: no such table: Dictionary1 (code 1): , while compiling: SELECT * FROM Dictionary1
                                                                                 at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
                                                                                 at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
                                                                                 at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
                                                                                 at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
                                                                                 at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
                                                                                 at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
                                                                                 at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
                                                                                 at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1316)
                                                                                 at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1163)
                                                                                 at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1034)
                                                                                 at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1202)
                                                                                 at com.elytelabs.myapplication.MainActivity.fetchData(MainActivity.java:142)
                                                                                 at com.elytelabs.myapplication.MainActivity.onCreate(MainActivity.java:82)
                                                                                 at android.app.Activity.performCreate(Activity.java:6039)
                                                                                 at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
                                                                                 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2295)
                                                                                 at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2404) 
                                                                                 at android.app.ActivityThread.access$900(ActivityThread.java:154) 
                                                                                 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1315) 
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                                 at android.os.Looper.loop(Looper.java:135) 
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:5296) 
                                                                                 at java.lang.reflect.Method.invoke(Native Method) 
                                                                                 at java.lang.reflect.Method.invoke(Method.java:372) 
                                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912) 
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:707) 
11-22 23:14:56.535 13193-13193/com.elytelabs.myapplication I/Process: Sending signal. PID: 13193 SIG: 9

这是我的代码。 数据库helper.java

    public class DatabaseHelper extends SQLiteOpenHelper{

        //The Android's default system path of your application database.
        private static String DB_PATH = "";

        private static String DB_NAME = "dictionary.db";

        private SQLiteDatabase myDataBase;

        private final Context myContext;

        /**
         * Constructor
         * Takes and keeps a reference of the passed context in order to access to the application assets and resources.
         * @param context
         */
        public DatabaseHelper(Context context) {

            super(context, DB_NAME, null, 1);
            this.myContext = context;
            DB_PATH= myContext.getDatabasePath(DB_NAME).toString();
        }

        /**
         * Creates a empty database on the system and rewrites it with your own database.
         * */
        public void createDataBase() throws IOException{

            boolean dbExist = checkDataBase();

            if(dbExist){
                //do nothing - database already exist
            }else{

                //By calling this method and empty database will be created into the default system path
                //of your application so we are gonna be able to overwrite that database with our database.
                this.getWritableDatabase();

                try {

                    copyDataBase();

                } catch (IOException e) {

                    throw new Error("Error copying database");

                }

            }

        }

        /**
         * Check if the database already exist to avoid re-copying the file each time you open the application.
         * @return true if it exists, false if it doesn't
         */
        private boolean checkDataBase(){
         //  this.getReadableDatabase();

            SQLiteDatabase checkDB = null;

            try{
                String myPath = DB_PATH ;
                checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);

            }catch(SQLiteException e){

                //database does't exist yet.

            }

            if(checkDB != null){

                checkDB.close();

            }

            return checkDB != null ? true : false;
        }

        /**
         * Copies your database from your local assets-folder to the just created empty database in the
         * system folder, from where it can be accessed and handled.
         * This is done by transfering bytestream.
         * */
        private void copyDataBase() 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 ;

            //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 openDataBase() throws SQLException{

            //Open the database
            String myPath = DB_PATH ;
            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) {

        }

        // Add your public helper methods to access and get content from the database.
        // You could return cursors by doing "return myDataBase.query(....)" so it'd be easy
        // to you to create adapters for your views.


    //add your public methods for insert, get, delete and update data in database.

}

这是我的主要活动.java

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    private AdView mAdView;
    private static RecyclerView.Adapter adapter;
    private RecyclerView.LayoutManager layoutManager;
    private static RecyclerView recyclerView;
    public static ArrayList<DictObjectModel> data;
    DatabaseHelper db ;
    ArrayList<String> wordcombimelist;
    ArrayList<String> meancombimelist;
    LinkedHashMap<String,String> namelist;
    SearchView searchView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.setDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);


        recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
        recyclerView.setHasFixedSize(true);
        db= new DatabaseHelper(this);
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        data = new ArrayList<DictObjectModel>();
        fetchData();

        // Banner Ads
        mAdView = (AdView) findViewById(R.id.adView);
        AdRequest adRequest = new AdRequest.Builder().build();
        mAdView.loadAd(adRequest);

    }
    public void fetchData()
    {
        db =new DatabaseHelper(this);
        try {

            db.createDataBase();
            db.openDataBase();

        }
        catch (Exception e)
        {
            e.printStackTrace();
        }


        namelist=new LinkedHashMap<>();
        int ii;
        SQLiteDatabase sd = db.getReadableDatabase();
        Cursor cursor = sd.query("Dictionary1" ,null, null, null, null, null, null);
        ii=cursor.getColumnIndex("word");
        wordcombimelist=new ArrayList<String>();
        meancombimelist= new ArrayList<String>();
        while (cursor.moveToNext()){
            namelist.put(cursor.getString(ii), cursor.getString(cursor.getColumnIndex("definition")));
        }
        Iterator entries = namelist.entrySet().iterator();
        while (entries.hasNext()) {
            Map.Entry thisEntry = (Map.Entry) entries.next();
            wordcombimelist.add(String.valueOf(thisEntry.getKey()));
            meancombimelist.add("- "+String.valueOf(thisEntry.getValue()));
        }

        for (int i = 0; i < wordcombimelist.size(); i++) {
            data.add(new DictObjectModel(wordcombimelist.get(i), meancombimelist.get(i)));
        }
        adapter = new CustomAdapter(data);
        recyclerView.setAdapter(adapter);

    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        final MenuItem item = menu.findItem(R.id.menu_search);
        final SearchView searchView = (SearchView)
                MenuItemCompat.getActionView(item);
        searchView.setQueryRefinementEnabled(true);


        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {return  false; }

            @Override
            public boolean onQueryTextChange(String newText) {


                newText = newText.toLowerCase();

                final ArrayList<DictObjectModel> filteredList = new ArrayList<DictObjectModel>();

                for (int i = 0; i < wordcombimelist.size(); i++) {

                    final String text = wordcombimelist.get(i).toLowerCase();
                    if (text.contains(newText)) {

                        filteredList.add(new DictObjectModel(wordcombimelist.get(i),meancombimelist.get(i)));
                    }
                }
                adapter = new CustomAdapter(filteredList);
                recyclerView.setAdapter(adapter);


                return true;
            }
        });
        return true;
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
            return false;

    }

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();

        if (id == R.id.nav_camera) {
            // Handle the camera action
        } else if (id == R.id.nav_gallery) {

        } else if (id == R.id.nav_slideshow) {

        } else if (id == R.id.nav_manage) {

        } else if (id == R.id.nav_share) {

        } else if (id == R.id.nav_send) {

        }

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }
}

3 个答案:

答案 0 :(得分:0)

试试这段代码,

 public class DatabaseHelper extends SQLiteOpenHelper{

        private static String DB_NAME = "dictionary.db";
        private SQLiteDatabase myDataBase;
        private final Context myContext;

        /**
         * Constructor
         * Takes and keeps a reference of the passed context in order to access to the application assets and resources.
         */
        public DatabaseHelper(Context context) {
            super(context, DB_NAME, null, 1);
            this.myContext = context;
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
          //write code create table.
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion{
        }

        // Add your public helper methods to access and get content from the database.
        // You could return cursors by doing "return myDataBase.query(....)" so it'd be easy
        // to you to create adapters for your views.


    //add your public methods for insert, get, delete and update data in database.

}

答案 1 :(得分:0)

你可以像下面这样尝试..如果添加任何表只需更改VERSION代码。这意味着如果添加新表,则必须将 VERSION = 1 更改为 VERSION = 2

public class DatabaseHelper extends SQLiteOpenHelper {

private static final String DBNAME = "yourdbname.db";
private static final int VERSION = 1;

public DatabaseHelper(Context context) {
    super(context, DBNAME, null, VERSION);
    // TODO Auto-generated constructor stub
}


@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("create table tablename(tablename_id integer primary key autoincrement,name text)");

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("DROP TABLE IF EXISTS tablename");
    onCreate(db);

  }

}

答案 2 :(得分:0)

我认为数据库实际上已成功复制和加载(打开),而且问题是复制的数据库在尝试以下操作时没有名为Dictionary1的表: - < / p>

Cursor cursor = sd.query("Dictionary1" ,null, null, null, null, null, null);

根据at com.elytelabs.myapplication.MainActivity.fetchData(MainActivity.java:142)

因此,您需要根据复制数据库中的表格更正表名

您可能希望使用this Q&A来显示数据库信息。

消息: -

11-22 23:14:56.455 13193-13193/com.elytelabs.myapplication E/SQLiteLog: (14) cannot open file at line 30052 of [b3bb660af9]
11-22 23:14:56.455 13193-13193/com.elytelabs.myapplication E/SQLiteLog: (14) os_unix.c:30052: (2) open(/data/data/com.elytelabs.myapplication/databases/dictionary.db) - 
11-22 23:14:56.455 13193-13193/com.elytelabs.myapplication E/SQLiteDatabase: Failed to open database '/data/data/com.elytelabs.myapplication/databases/dictionary.db'.
                                                                             android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database

etc .........

调用checkDatabase方法时的结果,因为数据库当时没有找到,因为它没有从资产中复制(应该这样做)。

该方法使用getReadableDatabase方法尝试查看数据库是否存在。此方法始终打印堆栈跟踪。

另一种方法可能是取代: -

    private boolean checkDataBase(){
     //  this.getReadableDatabase();
        SQLiteDatabase checkDB = null;
        try{
            String myPath = DB_PATH ;
            checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
        }catch(SQLiteException e){
            //database does't exist yet.
        }
        if(checkDB != null){

            checkDB.close();
        }
        return checkDB != null ? true : false;
    }

: -

    private boolean checkDataBase(){
        File db = new File(DB_PATH);
        if(db.exists()) return true;
        File dir = new File(db.getParent());
        if (!dir.exists()) {
            dir.mkdirs();
        }
        return false;
    }

这会尝试查看数据库文件是否存在(并且还在路径中创建了一个不存在的目录,例如在某些情况下,数据库目录可能不存在。)

如果使用上述内容,那么您的消息更像是: -

11-22 23:14:56.525 13193-13193/com.elytelabs.myapplication E/SQLiteLog: (1) no such table: Dictionary1
11-22 23:14:56.525 13193-13193/com.elytelabs.myapplication D/AndroidRuntime: Shutting down VM
11-22 23:14:56.525 13193-13193/com.elytelabs.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
                                                                             Process: com.elytelabs.myapplication, PID: 13193
                                                                             java.lang.RuntimeException: Unable to start activity ComponentInfo{com.elytelabs.myapplication/com.elytelabs.myapplication.MainActivity}: android.database.sqlite.SQLiteException: no such table: Dictionary1 (code 1): , while compiling: SELECT * FROM Dictionary1
                                                                                 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2342)
                                                                                 at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2404)
                                                                                 at android.app.ActivityThread.access$900(ActivityThread.java:154)
                                                                                 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1315)
                                                                                 at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                 at android.os.Looper.loop(Looper.java:135)
                                                                                 at android.app.ActivityThread.main(ActivityThread.java:5296)
                                                                                 at java.lang.reflect.Method.invoke(Native Method)
                                                                                 at java.lang.reflect.Method.invoke(Method.java:372)
                                                                                 at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
                                                                                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:707)
                                                                              Caused by: android.database.sqlite.SQLiteException: no such table: Dictionary1 (code 1): , while compiling: SELECT * FROM Dictionary1
                                                                                 at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
                                                                                 at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
                                                                                 at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
                                                                                 at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
                                                                                 at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
                                                                                 at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
                                                                                 at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
                                                                                 at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1316)
                                                                                 at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1163)
                                                                                 at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1034)
                                                                                 at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1202)
                                                                                 at com.elytelabs.myapplication.MainActivity.fetchData(MainActivity.java:142)
                                                                                 at com.elytelabs.myapplication.MainActivity.onCreate(MainActivity.java:82)