SQLiteOpenHelper:在物理设备上未调用onCreate()方法 [英] SQLiteOpenHelper: onCreate() method not called on physical device

查看:114
本文介绍了SQLiteOpenHelper:在物理设备上未调用onCreate()方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在运行于版本4.4的android模拟器上进行了许多测试. 在我的应用程序上,我使用SQLiteOpenHelper用一个表创建一个sqlite数据库:

I have done many tests on an android emulator running in version 4.4. On my app I create a sqlite database with one table using SQLiteOpenHelper:

package com.findwords.modeles;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;

import com.findwords.MainActivity;
import com.findwords.controleurs.MenuController;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * Created by louk on 02/01/14.
 */
public class DictionaryDbHelper extends SQLiteOpenHelper{

    // declare constants fields
    private static final String DB_PATH = "/data/data/com.findwords/databases/";
    private static final String DB_NAME = "dictionary_db";
    private static final int DB_VERSION = 1;

    // declared constant SQL Expression
    private static final String DB_CREATE =
            "CREATE TABLE dictionary ( " +
                    "_id integer PRIMARY KEY AUTOINCREMENT, " +
                    "word text NOT NULL, " +
                    "definition text NOT NULL, " +
                    "length integer NOT NULL " +
                    ");";

    private static final String DB_DESTROY =
            "DROP TABLE IF EXISTS dictionnary";

    /*
     * constructor
     */
    public DictionaryDbHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
    }

    /**
     * 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.getReadableDatabase();

            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(){

        SQLiteDatabase checkDB = null;

        try{
            String myPath = DB_PATH + DB_NAME;
            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 = MenuController.getInstance().getMainActivity().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();

    }

    /*
     * (non-Javadoc)
     * @see android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite.SQLiteDatabase)
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(DB_CREATE);

        try {
            createDataBase();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*
     * (non-Javadoc)
     * @see android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite.SQLiteDatabase, int, int)
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL(DB_DESTROY);
        onCreate(db);
    }
}

此外,我已经编写了一个打开方法的适配器:

Moreover I have written an adapter with a method open:

/*
 * open database connection
 */
public DictionaryDbAdapter open() throws SQLException {
    mDbHelper = new DictionaryDbHelper(mContext);
    mDb = mDbHelper.getWritableDatabase();
    return this;
}

它在模拟器上运行良好,因此可以调用SQLiteOpenHelper类的onCreate()方法并创建数据库,但不能在我的手机(Google Nexus 5)上调用它.

It's working well on the emulator so the onCreate() method of the SQLiteOpenHelper class is called and create the database, but is not called on my phone (Google Nexus 5).

我的手机没有植根,因此无法访问文件夹/data/data/com.myapp/databases.

My phone is not rooted so I can't access the folder /data/data/com.myapp/databases .

但是我希望该应用程序可以在任何手机上运行,​​所以我不想让我的手机植根.

However I want this application to work on any phone so I don't want to root my phone.

在此先感谢任何可以帮助我的人.

Thanks in advance to anyone who could help me.

推荐答案

让我尝试向您解释一些事情.

Let i try to explain you some things.

在连接数据库的应用程序中,我们指定数据库的名称和版本.在这种情况下,可能会发生以下情况:

In an application to connect to the database , we specify the name and version of the database . In this situation, the following may occur :

1)没有数据库.例如,在初始设置程序的情况下.在这种情况下,应用程序本身必须创建数据库及其中的所有表.而且,它已经在使用新创建的数据库.

1) There is no database . This may be for example in the case of initial setting program. In this case, the application itself must create the database and all the tables in it. And further, it is already working with the newly created database.

2)数据库存在,但其版本已过时.可能是情况更新.例如,该程序的新版本需要在旧表或新表中添加其他字段.在这种情况下,应用程序必须更新现有表并在必要时创建新表.

2) Database exists, but its version is outdated. It may be the case update. For example a new version of the program need additional fields in the old tables or new tables . In this case, the application must update existing tables and create new ones if necessary.

3)有一个数据库及其实际版本.在这种情况下,应用程序将成功连接到数据库并运行.

3) There is a database and its actual version . In this case, the application successfully connects to the database and running.

您知道,短语应用程序必须"等同于短语开发人员必须",即这是我们的任务.为了处理上述情况,我们需要创建一个继承自SQLiteOpenHelper的类.称之为DBHelper.此类将为我们提供在数据库不存在或过时的情况下创建或更新数据库的方法.

As you know , the phrase " application must " tantamount to the phrase " the developer must ", ie it is our task . To handle the situations described above , we need to create a class that inherits for SQLiteOpenHelper. Call it DBHelper. This class will provide us with methods to create or update the database in case of their absence or obsolescence.

onCreate-如果我们要连接的数据库不存在,则将调用该方法-这是您的情况

onCreate - a method that will be called if the database to which we want to connect - does not exist(it's your case)

这篇关于SQLiteOpenHelper:在物理设备上未调用onCreate()方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆