Issue
My app makes use of SQLiteDatabase to save two arraylists to separate tables.
I have noticed that since implementing the database, whenever it updates the database (involving dropping the tables, recreating them, then populating them with the arraylists) the app briefly freezes and I get the following message in logcat: "I/Choreographer: Skipped 236 frames! The application may be doing too much work on its main thread."
To confirm it was the updating, I removed the code used to update the database. Upon doing that, I no longer got the warning message, and my app didn't freeze.
This is the code inside my custom DB helper, which extends SQLiteOpenHelper, that is used to update the table:
public void insertData(ArrayList<SavedWifiHotspot> hotspots, ArrayList<MarkerOptions> markers) {
Log.d("insert LocationsDB", "Data inserted");
SQLiteDatabase db = this.getWritableDatabase();
ContentValues hotspotValues = new ContentValues();
ContentValues markerValues = new ContentValues();
for(SavedWifiHotspot hotspot : hotspots) {
hotspotValues.put("Ssid", hotspot.getSsid());
hotspotValues.put("Password", hotspot.getPassword());
hotspotValues.put("LocationName", hotspot.getHotspotLoc());
hotspotValues.put("Lat", hotspot.getLatitude());
hotspotValues.put("Lng", hotspot.getLongitude());
db.insert(HOTSPOT_TABLE_NAME, null, hotspotValues);
}
for(MarkerOptions marker : markers) {
markerValues.put("LocationName", marker.getTitle());
markerValues.put("Lat", marker.getPosition().latitude);
markerValues.put("Lng", marker.getPosition().longitude);
db.insert(LOCATION_TABLE_NAME, null, markerValues);
}
}
And this is the code used to clear the tables before they are updated:
public void clearData() {
Log.d("clear LocationsDB", "Tables cleared");
SQLiteDatabase db=this.getWritableDatabase();
String dropHSTable = "DROP TABLE IF EXISTS "
+ HOTSPOT_TABLE_NAME + ";";
String dropLocTable = "DROP TABLE IF EXISTS "
+ LOCATION_TABLE_NAME + ";";
db.execSQL(dropHSTable);
db.execSQL(dropLocTable);
createTables(db);
}
How should I go about updating my database in the background? I've read about threads, should I use a thread to do this?
Edit: This is the error, in reference to my comment.
FATAL EXCEPTION: AsyncTask #5
Process: com1032.cw2.fm00232.fm00232_assignment2, PID: 8830
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExe
at java.lang.Thread.run(Thread.java:818)cutor$Worker.run(ThreadPoolExecutor.java:587)
Caused by: java.util.ConcurrentModificationException
at java.util.ArrayList$ArrayListIterator.next(ArrayList.java:573)
at com1032.cw2.fm00232.fm00232_assignment2.LocationsDB$3.doInBackground(LocationsDB.java:124)
at at com1032.cw2.fm00232.fm00232_assignment2.LocationsDB$3.doInBackground(LocationsDB.java:119)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
For reference, line 124 is:
for(MarkerOptions marker: markers[0]) {
And line 119 is:
new AsyncTask<ArrayList<MarkerOptions>, Void, Void>() {
Edit2: Fixed the above problem. My app was invoking the insert data method using empty lists. So I've added .empty check before the insert data method.
Solution
An async task sounds like a good idea.
public void insertData(ArrayList<SavedWifiHotspot> hotspots, ArrayList<MarkerOptions> markers) {
Log.d("insert LocationsDB", "Data inserted");
new AsyncTask<ArrayList<SavedWifiHotspot>, Void, Void>() {
@Override
protected Void doInBackground(ArrayList<SavedWifiHotspot>... hotspots) {
ContentValues hotspotValues = new ContentValues();
for(SavedWifiHotspot hotspot : hotspots[0]) {
hotspotValues.put("Ssid", hotspot.getSsid());
hotspotValues.put("Password", hotspot.getPassword());
hotspotValues.put("LocationName", hotspot.getHotspotLoc());
hotspotValues.put("Lat", hotspot.getLatitude());
hotspotValues.put("Lng", hotspot.getLongitude());
db.insert(HOTSPOT_TABLE_NAME, null, hotspotValues);
}
}
}.execute(hotspots);
new AsyncTask<ArrayList<MarkerOptions>, Void, Void>() {
@Override
protected Void doInBackground(ArrayList<MarkerOptions>... options) {
ContentValues hotspotValues = new ContentValues();
for(MarkerOptions marker: options[0]) {
markerValues.put("LocationName", marker.getTitle());
markerValues.put("Lat", marker.getPosition().latitude);
markerValues.put("Lng", marker.getPosition().longitude);
db.insert(LOCATION_TABLE_NAME, null, markerValues);
}
}
}.execute(options);
}
public void clearData() {
Log.d("clear LocationsDB", "Tables cleared");
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
SQLiteDatabase db=this.getWritableDatabase();
String dropHSTable = "DROP TABLE IF EXISTS "
+ HOTSPOT_TABLE_NAME + ";";
String dropLocTable = "DROP TABLE IF EXISTS "
+ LOCATION_TABLE_NAME + ";";
db.execSQL(dropHSTable);
db.execSQL(dropLocTable);
createTables(db);
}
}.execute();
}
Answered By - Cory Roy
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.