我对SQLite有一个基本的困惑。我是否在主要的数据库实例? SQLite是在后台线程上运行还是必须将它放在AsyncTask中? (如果是这样,它应该与检索信息的那个相同吗?)
我在MainActivity的AsyncTask中解析HTTP POST(我得到了需要监视其信息的车辆列表),我想把这个ArrayList放到SQLite数据库中。
我该如何实现?现在我有一个内部类扩展MainActivity中的AsyncTask和一个单独的java文件DatabaseHandler扩展了SQLiteOpenHelper。
public class DatabaseHandler extends SQLiteOpenHelper {
// All Static variables
// Database Version
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "vehicleManager";
// Vehicle table name
private static final String TABLE_VEHICLE = "vehicle";
............. code
}
答案 0 :(得分:4)
这是我的工作,我创建了一个名为Database
的类static
,并且所有查询和所有数据库访问都通过它。如果我需要任何东西,我在static
类中创建一个Database
函数,它执行我需要的任何特定查询并返回Cursor
,然后我在代码中处理。这样,如果我需要更改任何查询,我只需要更改一个位置,而不是试图找到所有实例的代码。
当我调用Database
时,SQLiteHelper
类会在其中创建Database.open(context)
类的实例。当然,对Database
的所有来电都来自AsyncTask
或第二个帖子。
再一次,我个人的设计,随意做或者想出自己的设计。
public final class Database {
private static SQLHelper sqlhelper = null;
private static SQLiteDatabase database = null;
private static Context context = null;
/** Prevents Instances */
private Database(){};
/**
* Initiates the Database for access
* @param context Application context
*/
public static void initiate(Context context){
if (sqlhelper == null)
sqlhelper = new SQLHelper(context);
if (Database.context == null)
Database.context = context;
}
/**
* Opens the database for reading
* @throws SQLException if the database cannot be opened for reading
*/
public static void openReadable() throws SQLException{
if (database == null)
database = sqlhelper.getReadableDatabase();
}
/**
* Opens the database for writing
* Defaults to Foreign Keys Constraint ON
* @throws SQLException if the database cannot be opened for writing
*/
public static void openWritable() throws SQLException{
if ((database == null)? true : database.isReadOnly()) {
openWritable(true);
}
}
/**
* Opens the database for writing
* @param foreignKeys State of Foreign Keys Constraint, true = ON, false = OFF
* @throws SQLException if the database cannot be opened for writing
*/
public static void openWritable(boolean foreignKeys) throws SQLException{
database = sqlhelper.getWritableDatabase();
if (foreignKeys) {
database.execSQL("PRAGMA foreign_keys = ON;");
} else {
database.execSQL("PRAGMA foreign_keys = OFF;");
}
}
/**
* Closes the database
*/
public static void close(){
if (database != null){
database.close();
database = null;
}
if (sqlhelper != null){
sqlhelper.close();
sqlhelper = null;
}
}
/* Add functions here */
public static Cursor selectNames(){
openReadable();
return database.rawQuery("SELECT * FROM names", null);
}
}
final class SQLHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "core.db";
//private final Context context;
SQLHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
//this.context = context;
}
@Override
public void onCreate(SQLiteDatabase db){
// Create the tables
}
@Override
public void onOpen(SQLiteDatabase db){
super.onOpen(db);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
从活动访问:
Database.initiate(getBaseContext());
Cursor c = Database.selectNames();
来自Fragment:
Database.initiate(getActivity());
Cursor c = Database.selectNames();
答案 1 :(得分:2)
最好从背景线程加载/保存到数据库 对sqlite的调用是同步的,这意味着它们可以阻止您的UI线程。
您可以使用相同的asynctask或其他,这与您的应用程序的设计和您想要做的事情有关。重要的是不从主线程运行查询。
答案 2 :(得分:1)
正如@Plato所提到的,您可以保存/读取AsyncTask
中的数据,并在评论中询问您如何在数据库class
中创建公共功能,所以这里是:
public class DatabaseHandler extends SQLiteOpenHelper {
// All Static variables
// Database Version
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "vehicleManager";
// Vehicle table name
private static final String TABLE_VEHICLE = "vehicle";
//public function to do stuff with the database
public static void saveVehicle(/*arguments*/){ //note you should somhow pass data you want to save.... you can create as many arguments as you need
//Sql save logic with those arguments
}
当您需要保存数据时,您应该调用
DatabaseHandler.saveVehicle(/*arguments*/);
请注意,当您在班级中实施该方法时,您可能需要一个返回值来判断数据是否真的已保存。