我的应用程序第一次运行它会创建一个数据库,在该数据库中,它会从/res/raw
中的文件加载6,000行。我无法异步执行此操作,因为应用程序完全依赖于它。它在我的手机上快速运行 - 一个Moto X - 但它在我的所有模拟器中都非常慢,我担心它在较慢的设备上可能会慢一些,因此在应用程序执行之前让用户盯着空白屏幕几秒钟任何东西。
有没有办法在运行覆盖的SQLiteOpenHelper
的{{1}}方法时放置进度条,并让它更新进度条的详细程度,并显示类似“初始化数据以供首次使用!“?
答案 0 :(得分:3)
我通过在AsyncTask
中启动onCreate
然后仅在“AsyncTask”结尾处加载布局(或者先前已加载数据)来解决此问题。它作为加载屏幕工作得很漂亮。我按照本教程http://www.41post.com/4588/programming/android-coding-a-loading-screen-part-1(更详细地解释了详细信息)然后根据我的需要对其进行了一些更改(例如加载原始资源)。
我应该说虽然它是异步的,因为主要布局没有加载,但是用户必须等待加载完成才能继续,所以希望这意味着它会异步赢得&#39 ;根据数据库的不同,应用程序会对您造成问题。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences sharedPref = getSharedPreferences(getString(R.string.preference_file_key), Context.MODE_PRIVATE);
dataAddedToDB = (sharedPref.getBoolean(PXS_RXS_UPDATE, false));
if (!dataAddedToDB) {
new LoadViewTask(this).execute();
} else {
setContentView(R.layout.activity_main);
}
}
在AsyncTask
中,它会加载数据库,显示它有多远并显示您的消息,然后继续显示最后的布局。 (顺便说一句,这样做有助于锁定屏幕方向,以防止它弄乱它)。
编辑:publishProgress(counter);
将任务所在的值传递给onProgressUpdate()
。
private class LoadViewTask extends AsyncTask<Void, Integer, Void> {
private Context context;
public LoadViewTask(Context context) {
this.context = context.getApplicationContext();
}
@Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setTitle("Loading...");
progressDialog.setMessage("Initializing data for first use!");
progressDialog.setCancelable(false);
progressDialog.setIndeterminate(false);
// this counts how many line to be added to the database so it can later tell how far it has got.
final Resources resources2 = context.getResources();
InputStream inputStream2 = resources2.openRawResource(R.raw.rawherbaldata);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream2));
int lineCount = 0;
try {
String line;
while ((line = reader.readLine()) != null) {
lineCount++;
}
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
progressDialog.setMax(lineCount);
progressDialog.setProgress(0);
progressDialog.show();
}
@Override
protected Void doInBackground(Void... params) {
HerbalDatabaseOpenHelper mHerbalDbHelper = new HerbalDatabaseOpenHelper(MainActivity.this);
SQLiteDatabase db = mHerbalDbHelper.getWritableDatabase();
int counter = 0;
final Resources resources2 = context.getResources();
InputStream inputStream2 = resources2.openRawResource(R.raw.rawherbaldata);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream2));
db.beginTransaction();
try {
int lineNumber = 1;
String line;
while ((line = reader.readLine()) != null) {
// CODE FOR ENTERING LINE INTO DATABASE
// EDIT: the following keeps the task updated on where it has got to, passing the count to onProgressUpdate()
counter++;
publishProgress(counter);
}
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
db.setTransactionSuccessful();
db.endTransaction();
db.close();
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
progressDialog.setProgress(values[0]);
}
@Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
SharedPreferences sharedPref = getSharedPreferences(getString(R.string.preference_file_key), Context.MODE_PRIVATE);
pxsRxsUpdate = true;
SharedPreferences.Editor editor = sharedPref.edit();
editor.putBoolean(PXS_RXS_UPDATE, pxsRxsUpdate);
editor.commit();
// initialize the View
setContentView(R.layout.activity_main);
}
}
答案 1 :(得分:2)
您可以使用另一个显示进度对话框的中间活动,然后在完成后将其发送回主活动。
首先,如果数据库已经创建,你需要一个布尔值的静态方法。
然后在你的活动内onCreate
在必要时给中间人打电话:
DbHelper mDbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!DbHelper.isDbCreated()) {
Intent intent = new Intent(this, DbActivity.class);
startActivity(intent);
finish();
return;
}
// Do normal stuff like instantiating the helper and so on
mDbHelper = new DbHelper();
...
}
然后在这个“中间人”活动内部显示ProgressDialog并创建数据库。
完成后,隐藏对话框并返回主要活动:
mProgress.dismiss();
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
return;
如果正确创建了静态方法isDbCreated()
,则在创建数据库之前不会显示MainActivity的内容。
修改强>
这是我用来检查数据库的方法。也许它会对你有所帮助。
public boolean isDbCreated() {
String sDatabasePath = context.getDatabasePath(DB_NAME).getPath();
SQLiteDatabase tmpDb = null;
if (mContext.getDatabasePath(DB_NAME).exists()) {
try {
tmpDb = SQLiteDatabase.openDatabase(sDatabasePath, null,
SQLiteDatabase.OPEN_READONLY);
tmpDb.close();
} catch (SQLiteException e) {
e.printStackTrace();
}
} else {
Log.e(TAG, "DB file doesn't exist.");
// If the parent dir doesn't exist, create it
File parentDir = new File(mContext.getDatabasePath(DB_NAME).getParent());
if (!parentDir.exists()) {
if (parentDir.mkdirs()) {
Log.d(TAG, "Successfully created the parent dir:" + parentDir.getName());
} else {
Log.e(TAG, "Failed to create the parent dir:" + parentDir.getName());
}
}
}
return (tmpDb != null);
}