线程中的openOrCreateDatabase

时间:2013-12-31 17:43:31

标签: android sql multithreading

在我的主类(MainActivity.java)中,我调用一个执行HttpResponse的新线程,并根据该响应的结果创建一个数据库并使用HttpResponce填充它。

这在我的主类(MainActivity.java)中完美运行。问题是我有多个Threads,主类(MainActivity.java)变得混乱,当我尝试为Thread创建另一个类(Class2.java)时,我尝试使用openOrCreateDatabase()创建数据库时出错。

这是我的代码: MainActivity.java

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        Class2 class2 = new Class2();
        class2.execute();
    }
}

Class2.java

public class lvl3 extends AsyncTask<String, Integer, String>{

@Override
protected String doInBackground(String... params) {
    try{
        //this is the HTTPRequest that works
    }
    try
    {
        // this is the problem
        SQLiteDatabase db = openOrCreateDatabase("MyDB", MODE_PRIVATE, null);
    }
}

我尝试了以下错误:

 SQLiteDatabase db = openOrCreateDatabase("MyDB", MODE_PRIVATE, null);
 MODE_PRIVATE cannot be resolved to a variable


SQLiteDatabase db = openOrCreateDatabase("MyDB", Context.MODE_PRIVATE, null);
The method openOrCreateDatabase(String, int, null) is undefined for the type Class2

SQLiteDatabase db = openOrCreateDatabase("MyDB", MODE_PRIVATE, null);
MODE_PRIVATE cannot be resolved to a variable

SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase("MyDB", Context.MODE_PRIVATE , null);
The method openOrCreateDatabase(String, SQLiteDatabase.CursorFactory, DatabaseErrorHandler) in the type SQLiteDatabase is not applicable for the arguments (String, int, null)

SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase("MyDB", MODE_PRIVATE , null);
MODE_PRIVATE cannot be resolved to a variable

SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase("MyDB", null);

程序运行但我在这里得到一些错误只是几个:

12-31 10:22:33.116: E/SQLiteLog(2045): (14) cannot open file at line 30176 of [00bb9c9ce4]
12-31 10:22:33.126: E/SQLiteLog(2045): (14) os_unix.c:30176: (2) open(//MyDB) - 
12-31 10:22:33.136: E/SQLiteDatabase(2045): Failed to open database 'MyDB'.
12-31 10:22:33.136: E/SQLiteDatabase(2045): android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database
12-31 10:22:33.136: E/SQLiteDatabase(2045):     at com.example.matthew28project.Class2.doInBackground(Class2.java:57)
12-31 10:22:33.136: E/SQLiteDatabase(2045):     at com.example.matthew28project.Class2.doInBackground(Class2.java:1)
12-31 10:22:33.136: E/SQLiteDatabase(2045):     at android.os.AsyncTask$2.call(AsyncTask.java:287)
12-31 10:22:33.216: E/AndroidRuntime(2045): FATAL EXCEPTION: AsyncTask #2
12-31 10:22:33.216: E/AndroidRuntime(2045): java.lang.RuntimeException: An error occured while executing doInBackground()
12-31 10:22:33.216: E/AndroidRuntime(2045):     at android.os.AsyncTask$3.done(AsyncTask.java:299)
12-31 10:22:33.216: E/AndroidRuntime(2045):     at com.example.matthew28project.Class2.doInBackground(Class2.java:57)
12-31 10:22:33.216: E/AndroidRuntime(2045):     at com.example.matthew28project.Class2.doInBackground(Class2.java:1)`

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

我建议您使用单例模式的注册表来管理SQLite数据库,从而获得SQLiteOpenHelper的子项,您可以从以下代码开始。

import java.util.HashMap;

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

public class MySQLiteOpenHelper extends SQLiteOpenHelper {

    // Instances
    private static HashMap<Context, MySQLiteOpenHelper> mInstances;

    // Member object
    private Context mContext;

    // Database metadata
    public static final String DATABASE_NAME = "MySQLiteOpenHelper.db";
    public static final int DATABASE_VERSION = 1;

    // Table names
    public static final String TABLE_ONE = "TABLE_ONE";
    public static final String TABLE_TWO = "TABLE_TWO";

    // Create table querys
    private static final String QUERY_CREATE_TABLE_ONE = String.format(
            "CREATE TABLE IF NOT EXISTS %s (" +
                    "`%s` INTEGER primary key autoincrement, " +
                    "`%s` INTEGER, " +
                    "`%s` INTEGER, " +
            ");",
            TABLE_ONE,
            "column_one", "column_two", "column_three");

    private static final String QUERY_CREATE_TABLE_TWO = String.format(
            "CREATE TABLE IF NOT EXISTS %s (" +
                    "`%s` INTEGER primary key autoincrement, " +
                    "`%s` INTEGER, " +
                    "`%s` INTEGER, " +
            ");",
            TABLE_TWO,
            "column_one", "column_two", "column_three");

    private MySQLiteOpenHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);

        mContext = context;
    }

    public static MySQLiteOpenHelper getInstance(Context context) {
        if(mInstances == null)
            mInstances = new HashMap<Context, MySQLiteOpenHelper>();

        if(mInstances.get(context) == null)
            mInstances.put(context, new MySQLiteOpenHelper(context));

        return mInstances.get(context);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(QUERY_CREATE_TABLE_ONE);
        db.execSQL(QUERY_CREATE_TABLE_TWO);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //TODO Upgrade your database here

    }

}

之后,您可以通过获取SQLiteDatabaseOpenHelper和SQLiteDatabase来创建自己的数据库访问命令模式,如下所示。

MySQLiteOpenHelper mySQLiteOpenHelper = MySQLiteOpenHelper.getInstance(context);
mySQLiteOpenHelper.getReadableDatabase();

如果仍然遇到多线程环境,可以尝试将getReadableDatabase方法重写为SQLiteDatabaseOpenHelper子类中的synchronized方法。

@Override
public synchronized SQLiteDatabase getReadableDatabase() {
    return super.getReadableDatabase();
}