The first time my app runs it creates a database in which it loads 6,000 rows from a file in /res/raw
. I can't do this asynchronously as the app depends on it entirely. It runs rapidly on my phone - a Moto X - but it's really slow in all my emulators and I'm concerned it could be a bit slower on slower devices thus making the user stare at a blank screen for a few seconds before the app does anything.
Is there a way to put a progress bar while running the overrided SQLiteOpenHelper
's onCreate()
methood and have it update the progress bar with how far along it is, with a message saying something like "Initializing data for first use!"?
I solved this problem by starting an AsyncTask
in onCreate
and then only loading the layout at the end of the 'AsyncTask` (or if the data had previously been loaded). It works beautifully as a loading screen. I followed this tutorial http://www.41post.com/4588/programming/android-coding-a-loading-screen-part-1 (which explains the details more) then changed it a bit for my needs (such as loading a raw resource).
I should say that although it does it asynchronously because the main layout hasn't loaded the user has to wait for the loading to complete before he or she can continue, so hopefully that means it doing it asynchronously won't be a problem for you with the app depending on the database.
@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);
}
}
In the AsyncTask
it loads the database showing how far it has got and showing your message and then only goes on to show the layout at the end. (BTW, it is helpful to lock the screen orientation while doing this to stop it messing it up).
EDIT: publishProgress(counter);
passes the value of where the task has got to to 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);
}
}