IAm*_*ale 6 android android-sqlite
我正在使用SQLite资产助手库来处理设置和升级我的应用程序数据库的肮脏工作.它工作得很好但不幸的是我还没有找到一种方法来通知用户何时库:
A)首次加载数据库(通过从\ assets\databases \文件夹中解压缩)
要么
B)升级数据库(使用\ assets\datates中升级的数据库文件中的信息)
我尝试将此代码放在我的应用程序的主Activity.onCreate()中,以为我可以在主线程上加载数据库(如果它不存在),同时用不可解雇的AlertDialog分散用户的注意力:
File dbFile=this.getDatabasePath("gShoJMDict");
Boolean dbExists = dbFile.exists();
Log.i("ActivityStartScreen", String.valueOf(dbExists));
if(!dbExists)
{
DialogFirstRun dialogFirstRun = new DialogFirstRun();
dialogFirstRun.show(getSupportFragmentManager(), "dialogFirstRun");
dialogFirstRun.setCancelable(false);
DictHelper helper = new DictHelper(this);
helper.getReadableDatabase();
helper.close();
dialogFirstRun.dismiss();
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,基于LogCat条目,SQLite资产助手会在onCreate()之前检查数据库是否存在,所以当上面的代码块运行时,数据库已经存在,因此对话框永远不会出现.
我正在使用ContentProvider,并且我已经验证我只是在query()或update()中调用getReadableDatabase().我的ContentProvider的onCreate()看起来像这样......
@Override
public boolean onCreate()
{
// Load our database
gdb = new JMDictHelper(getContext());
return true;
}
Run Code Online (Sandbox Code Playgroud)
...但是尽管移动了gdb = new JMDictHelper(getContext()); 在查询()或更新()之前,SQLite资产助手库仍然可以在我通知用户之前很好地加载数据库.
在这种情况下,我可以做什么来拦截数据库的初始设置或升级,并通知用户应用程序正在忙于执行这些任务?现在,应用程序只是在那里做任何事情,直到库完成 - 这对于测试很好,因为我知道期待它,但是当我准备让应用程序上线时,我不能这样做.
万一你仍然想知道这个或其他人有这个问题,这里是我刚刚实现的类似问题的解决方案.在调用getReadableDatabase()或getWritableDatabase()之前,SQLiteAssetHelper不会复制数据库.如果在MainActivity.onCreate()之前调用其中一个方法,可能是因为您在ContentProvider的onCreate()方法中调用它.这是文档中的方法描述:
实现此目的以在启动时初始化您的内容提供程序.在应用程序启动时,应用程序主线程上的所有已注册内容提供程序都会调用此方法.它不能执行冗长的操作,否则应用程序启动将被延迟.
您应该推迟使用内容提供程序(通过查询(Uri,String [],String,String [],String),insert(Uri,ContentValues)等)来进行非常重要的初始化(例如打开,升级和扫描数据库). .延迟初始化可以使应用程序启动更快,如果提供程序不需要,则可以避免不必要的工作,并且可以阻止数据库错误(例如完整磁盘)停止应用程序启动.
如果您使用SQLite,SQLiteOpenHelper是一个有用的实用程序类,可以轻松管理数据库,并将自动推迟打开直到第一次使用.如果使用SQLiteOpenHelper,请确保避免从此方法调用getReadableDatabase()或getWritableDatabase().(相反,覆盖onOpen(SQLiteDatabase)以在首次打开数据库时初始化数据库.)
您可以对getReadableDatabase()或将您的ContentProvider的实际访问getWritableDatabase()您的来电,描述在这里.
既然您的ContentProvider没有提供帮助,您可以检查MainActivity.onCreate()中是否存在数据库,并在必要时在显示ProgressDialog时将其复制到后台线程中:
// Create an AsyncTask to copy the database in a background thread while
// displaying a ProgressDialog.
private class LoadDatabaseTask extends AsyncTask<Context, Void, Void> {
Context mContext;
ProgressDialog mDialog;
// Provide a constructor so we can get a Context to use to create
// the ProgressDialog.
LoadDatabasesTask(Context context) {
super();
mContext = context;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
mDialog = new ProgressDialog(mContext);
mDialog.setMessage(mContext.getString("Loading database..."));
mDialog.show();
}
@Override
protected Void doInBackground(Context... contexts) {
// Copy database.
new MyAssetHelper(contexts[0]).getReadableDatabase();
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
mDialog.dismiss();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
// Install databases if necessary.
File database = getDatabasePath(DB_NAME);
if (!database.exists()) {
new LoadDatabaseTask(this).execute(this, null, null);
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2075 次 |
| 最近记录: |