In my application I download a lot of data (around 3000-4000 records) from server and then insert it to database. The process takes very long time, so I want to show progress dialog while the whole process runs. I implemented the progress dialog inside of the AsyncTask class where I am downloading data and inserting it to database. Here is the code of AsyncTask:
@Override
protected void onPreExecute() {
super.onPreExecute();
a.runOnUiThread(new Runnable(){
@Override
public void run() {
pd.setTitle("Загрузка необходимых данных");
pd.setMessage("Пожалуйста подождите");
pd.setIndeterminate(true);
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pd.setProgress(0);
pd.setCancelable(false);
pd.show();
}
});
}
protected Map<String, String> doInBackground(String... strs) {
return getMaterials();
}
@Override
protected void onPostExecute (Map<String, String> map) {
a.runOnUiThread(new Runnable(){
@Override
public void run() {
pd.dismiss();
}
});
}
public Map<String,String> getMaterials() {
int maxNum = getMaxIndex("materials");
Map<String,String> materials = null;
DBConnection db = new DBConnection(context);
Date end = new Date(System.currentTimeMillis());
String exml = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" +
"<REQUEST format=\"json\" client=\"exstroy\" action=\"get\" enddate=\""+ end.toString() + "\" " +
"startdate=\"2000-01-28\" POINT_ID=\"3\" session=\"" + session_id + "\" catalogname=\"nomenclature\" type=\"cataloglist\">" +
"<LIST firstmrid = \"0\" lastmrid=\""+ maxNum + "\"></LIST>" +
"</REQUEST>";
try{
PrintWriter writer = new PrintWriter(Environment.getExternalStorageDirectory().getPath() + "/data.xml", "UTF-8");
writer.println(exml);
writer.close();
} catch (IOException e) {
}
String charset = "UTF-8";
File uploadFile1 = new File(Environment.getExternalStorageDirectory().getPath() + "/data.xml");
String requestURL = "blahblah.com";
try {
MultipartUtility multipart = new MultipartUtility(requestURL, charset);
multipart.addFilePart("datafile", uploadFile1);
List<String> response = multipart.finish();
materials = new HashMap<String, String>();
String s = "{ " + response.get(1) + "}";
JSONObject json = new JSONObject(s);
JSONObject cataloglist = json.getJSONObject("cataloglist");
JSONArray array = cataloglist.names();
//db.clearNomenclature();
ArrayList<Map<String, Object>> data = new ArrayList<Map<String, Object>>(5000);
int max = 0;
for(int n = 0; n < array.length(); n++)
{
if (n > max)
max = n;
JSONObject object = cataloglist.getJSONObject(array.getString(n));
Map<String, Object> map;
map = new HashMap<String, Object>();
if (object.has("version"))
map.put("version", object.getInt("version"));
else
map.put("version", 0);
if (object.has("name"))
map.put("name", object.getString("name"));
else
map.put("name", "");
if (object.has("uuid"))
map.put("uuid", object.getString("uuid"));
else
map.put("uuid", "");
if (object.has("uuid"))
map.put("measure", object.getString("measure"));
else
map.put("measure", "");
data.add(map);
}
db.insertNom(data);
} catch (IOException ex) {
System.err.println(ex);
} catch (JSONException e) {
e.printStackTrace();
}
ArrayList<Map<String, String>> measures = getMeasures();
db.measures(measures);
return materials;
}
While downloading data is performed the progress dialog is showed, but when it reaches database insertion progress dialog is dismissed. Here is the part of the code for the database insertion:
public void insertNom(final ArrayList<Map<String, Object>> data) {
dbOpen();
database.execSQL("CREATE TABLE IF NOT EXISTS "+"nomenclature"+
" ("+"ID"+" INTEGER PRIMARY KEY AUTOINCREMENT, "+
"name TEXT, version INTEGER, measure UUID, uuid UUID)");
dbClose();
Runnable runnable = new Runnable() {
@Override
public void run() {
for (int i = 0; i < data.size(); i++) {
dbOpen();
Map<String, Object> map = data.get(i);
ContentValues cv = new ContentValues();
cv.put("name", (String) map.get("name"));
cv.put("version", (int) map.get("version"));
cv.put("uuid", (String) map.get("uuid"));
cv.put("measure", (String) map.get("measure"));
database.insert("nomenclature", null, cv);
dbClose();
}
}
};
new Thread(runnable).start();
}
I tried to do it in a separate thread as you can see in the code above, also I have tried to do it just in the doInBackgroung method of AsyncTask. Both ways dismissed the progress dialog. Additionally there is one more issue, while downloading data from server is finished relatively fast: 3-4 seconds, inserting to database takes around 20 seconds, even more. Is there any way to do it faster? If not what causes the progress dialog to dismiss?
Around 3000-4000 records needed to insert in table. do following chnages to speed up insertion :
1. If data is inserted directly from JSON to table then no need to hold JSONObject's in
HashMap
. just useJsonReader
which reads a JSON encoded value as a stream of tokens. and call insert method for every object. (Optional but if you do in current code then it will also reduce time of reading and packing data in Collection)2. Use only
doInBackground
and remove Thread frominsertNom
method.3. make bulk insert using Android db Transaction in
doInBackground
. like: