내 응용 프로그램에서 서버에서 많은 데이터 (약 3000-4000 레코드)를 다운로드 한 다음 데이터베이스에 삽입합니다. 프로세스는 매우 오랜 시간이 걸리기 때문에 전체 프로세스가 실행되는 동안 진행률 대화 상자를 표시하려고합니다. AsyncTask 클래스 내부에 진행 대화 상자를 구현하여 데이터를 다운로드하고 데이터베이스에 삽입합니다. 여기에 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;
}
동안 진행 대화 상자가 나타났다되어 있지만 데이터베이스 삽입에 도달 할 때 진행 대화 상자가 그라운드를 떠납니다.
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();
}
가 나는 또한 나는 단지의 doInBackgroung 방법에 그것을 할 시도, 위의 코드에서 볼 수 있듯이 별도의 스레드에서 작업을 수행하려고 다음은 데이터베이스 삽입 코드의 일부입니다 AsyncTask. 두 방법 모두 진행 대화 상자를 닫습니다. 또한 서버에서 데이터를 다운로드하는 데 3-4 초가 걸리며 데이터베이스에 삽입하는 데 약 20 초 정도 걸립니다. 더 빨리 할 수있는 방법이 있습니까? 진행 대화 상자를 닫는 원인은 무엇입니까?
코드 품질 힌트 : 문자열 리터럴을 모든 곳에서 반복하는 대신 소스 코드에서 ** 상수 **를 사용하는 것이 좋습니다. 그건 ** 슈퍼 나쁜 ** 연습입니다! – GhostCat
@GhostCat 고마워 젠장, 안드로이드에 좀 초보자 오전, 그 나쁜 습관을 없애려고 노력할 것입니다 – Sanzhar