【问题标题】:onCreate method doesn't get called in DatabaseHandler extends SQLiteOpenHelper在 DatabaseHandler 扩展 SQLiteOpenHelper 中未调用 onCreate 方法
【发布时间】:2013-02-05 12:56:28
【问题描述】:

这基本上是我的第一个 android 应用程序,我一直在尝试使用预填充的 sqllite 数据库来满足我的要求。

我的问题是 onCreate 函数没有被调用。

我从很多地方提取了一些代码,并将它们组合成这个类。

Updating prepopulated database in Android

http://www.androidhive.info/2011/11/android-sqlite-database-tutorial/

还有一些来自 android.com 的其他人

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Locale;
import java.util.Random;

import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class DatabaseHandler extends SQLiteOpenHelper {

    SQLiteDatabase db;
    private static final String TAG = "DataBaseHelper";
    int id = 0;
    Random random = new Random();
    private SQLiteDatabase myDataBase;
    private final Context myContext;

    // Constructor
    public DatabaseHandler(Context context) {
        super(context, DefinitionContract.DATABASE_NAME, null, DefinitionContract.DATABASE_VERSION);
        Log.d(TAG, "DatabaseHandler constructor called\n");
        db = getWritableDatabase();
        this.myContext = context;
        //createDB();
    }

    @Override
    public void onCreate(SQLiteDatabase db){
        Log.d(TAG, "onCreate called\n");
        createDB();
    }

    // Upgrading database
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.d(TAG, "onUpgrade called\n");
        Log.w(TAG, "Upgrading DB from version " + oldVersion + " to " +
                    newVersion + ", which will destroy all old data");

        // Drop older table if existed
        String sql  = "DROP TABLE IF EXISTS " + DefinitionContract.CATEGORY_TABLE_NAME;
        db.execSQL(sql);

        sql = "DROP TABLE IF EXISTS " + DefinitionContract.CONTENTS_TABLE_NAME;
        db.execSQL(sql);

        // Create table again
        onCreate(db);
    }

    public void createDataBase(SQLiteDatabase db) {
        Log.d(TAG, "createDataBase called\n");
        createDB();
        db.execSQL(DefinitionContract.CREATE_CATEGORY_TABLE);
        db.execSQL(DefinitionContract.CREATE_CONTENTS_TABLE);
    }

    private void createDB() {
        Log.d(TAG, "createDB called\n");
        boolean dbExist = dbExists();
        Log.d("SQL Helper", "Condition:\n");
        if(!dbExist) {
            Log.d("SQL Helper", "Condition 1\n");
            copyDataBase();
        } else if(dbExist) {
            Log.d("SQL Helper", "Condition 2\n");
            copyDataBase();
        }
    }

    private boolean dbExists() {
        Log.d(TAG, "dbExists called\n");
        //File dbFile = new File(DefinitionContract.DATABASE_PATH + DefinitionContract.DATABASE_NAME);
        //return dbFile.exists();

        SQLiteDatabase db = null;
        try {
            String dbPath = DefinitionContract.DATABASE_PATH + DefinitionContract.DATABASE_NAME;
            db = SQLiteDatabase.openDatabase(dbPath, null, SQLiteDatabase.OPEN_READWRITE);
            db.setLocale(Locale.getDefault());
            db.setLockingEnabled(true);
            db.setVersion(DefinitionContract.DATABASE_VERSION);
        }
        catch(SQLiteException e){
            Log.e("SQL Helper", "database not found");
        }
        if(db != null) {
            db.close();
        }
        return db != null ? true : false;
    }

    private void copyDataBase() {
        Log.d(TAG, "copyDataBase called \n");
        InputStream iStream = null;
        OutputStream oStream = null;
        String outFilePath = DefinitionContract.DATABASE_PATH + DefinitionContract.DATABASE_NAME;
        try{
            iStream = myContext.getAssets().open(DefinitionContract.DATABASE_NAME_EXT);
            oStream = new FileOutputStream(outFilePath);
            byte[] buffer = new byte[1024];
            int length;
            while((length = iStream.read(buffer))>0) {
                oStream.write(buffer,0,length);
            }
            oStream.flush();
            oStream.close();
            iStream.close();
        }
        catch(IOException ioe){
            throw new Error("Problem copying database from resource file.");
        }
    }

    public void openDataBase() throws SQLException {
        String myPath = DefinitionContract.DATABASE_PATH + DefinitionContract.DATABASE_NAME_EXT;
        myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
    }

    @Override
    public synchronized void close() {
        Log.d(TAG, "close called\n");
        if (myDataBase != null)
            myDataBase.close();
        super.close();
    }

    public void readDB() {
        Log.d(TAG, "readDB called\n");
        String selectQuery = "SELECT  * FROM " + DefinitionContract.DATABASE_ONLYNAME+"."+DefinitionContract.CATEGORY_TABLE_NAME;
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);

        // looping through all rows and adding to list
        if (cursor.moveToFirst()) {
            do {
                int arraySize = cursor.getColumnCount();
                String newlog   = "arraySize=" + arraySize + "*****";
                for(int i = 0; i < arraySize; i++) {
                    newlog  = newlog + cursor.getString(i)+ "\n";
                }

                Log.d("Details: ", newlog);
            } while (cursor.moveToNext());
        }
    }

}

我已经进行了谷歌搜索并尝试修复它,但它还没有工作。

Android SQLiteOpenHelper : onCreate() method is not called. Why?

SQLiteOpenHelper failing to call onCreate?

LogCat 仅显示“调用 DataBaseHandler 构造函数”,然后显示“关闭 VM”

但是,如果我从构造函数中删除 db = getWritableDatabase(); 行,它会进一步工作并显示正在调用 readDB() 函数。

一些可能有助于理解我的代码的定义:

public static final String DATABASE_NAME        = "mydb.db";

public static final String DATABASE_NAME_EXT        = "mydb.sqllite";

// Database path
public static final String DATABASE_PATH = "/data/data/com.abhishekgdotcom.collection/databases/";

有帮助吗?

【问题讨论】:

    标签: android sqlite


    【解决方案1】:

    好吧,onCreate() 方法对我不起作用的真正原因是因为它仅在应用程序第一次运行时被调用。或者,当您更改 DATABASE_VERSION 时,onUpgrade 会被调用,而后者又会再次调用 onCreate 方法。

    我相信这是默认的 android 工作。

    P.S 我可以通过更改数据库版本或从 /data/data/packagename/databases/ 删除数据库文件来让 onCreate 每次都正常工作

    【讨论】:

      【解决方案2】:

      我会向您推荐另一种代码组织,因为您在同一个类中制作了许多不相关的东西。通常一个好的设计是定义一个继承自SQLiteHelperOpenHelper 类,它只是创建或更新数据库而已。然后,从另一个外部类(通常来自您的活动),实例化 OpenHelper 类,然后从那里调用 getWritableDatabase()。也许你会很容易找到这个错误。

      【讨论】:

      • 所以基本上这个想法是从活动中调用 getReadableDatabase() 。我是否也应该传递来自活动类的查询?
      • 或多或少,我通常定义一个 OpenHelper 类,正如我在回答中所说,以及一个检索 getWritableDatabase() 并进行所有查询的 DataManager 类。我将 DataManager 的一个实例存储在我的 Application 实例中(在其 onCreate 方法中),因此它可以由我的所有活动共享(避免并发问题的最佳方法)。从活动中,我从我的 Application 实例中检索 DataManager 实例,然后通过它的方法进行查询。只有 DataManager 使用 OpenHelper,没有其他人使用。
      • 我的错误似乎已解决,但现在弹出另一个错误说(5) database is locked。知道为什么吗?
      猜你喜欢
      • 2013-03-13
      • 1970-01-01
      • 1970-01-01
      • 2011-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多