我从服务器下载文件,然后在本地数据库中解析和插入,而这个操作我正在使用进度条显示操作进度。由于文件非常大,因此需要2-4分钟进行解析我得到了ANR在进度条上,进度条在下载完成后没有得到更新它只显示50%的进度。如何避免这个ANR?我附上我的代码如下......
@Override
protected void onPreExecute()
{
flag = false;
progressCount = 0;
ProgressDialog progressBar = DdownoadProgressBar(context,
progressCount);
progressBar.show();
}
@Override
protected Integer doInBackground(String... urls) {
checkNetworkConnection();
if (connectionFlag) {
downloadFile1();
progressCount = 1;
publishProgress(progressCount);
downloadFile2();
progressCount = 2;
publishProgress(progressCount);
downloadFile3();
progressCount = 3;
publishProgress(progressCount);
downloadFile4();
progressCount = 4;
publishProgress(progressCount);
downloadFile5();
progressCount = 5;
publishProgress(progressCount);
downloadFile6();
progressCount = 6;
publishProgress(progressCount);
downloadflag = true;
}
return null;
}
@Override
protected void onProgressUpdate(Integer... progress)
{
Log.v(TAG, "In progressUpdate...");
progressBar.setProgress(progressCount);
}
@Override
protected void onPostExecute(Integer progress) {
if (downloadflag) {
try {
Log.v(TAG, "Inside onPostExecute....");
parseFile1();
progressCount=7;
publishProgress(progressCount);
parseFile2();
progressCount=8;
publishProgress(progressCount);
parseFile3();
progressCount=9;
publishProgress(progressCount);
parseFile4();
progressCount=10;
publishProgress(progressCount);
parseFile5();
progressCount=11;
publishProgress(progressCount);
parseFile6();
progressCount=12;
publishProgress(progressCount);
progressBar.dismiss();
Toast.makeText(SynchronizeData.this,"Data is successfully downloaded from server.......", Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
} else {
progressBar.dismiss();
Toast.makeText(
getApplicationContext(),
"File is not downloaded....Error in network connection...........",Toast.LENGTH_LONG).show();
Log.v(TAG, "File is not downloaded...............");
}
}
答案 0 :(得分:1)
将解析逻辑移动到doInBackground方法中。没有理由在后台线程上进行Web调用并在UI线程上进行解析。
答案 1 :(得分:1)
正如Rich所说:在doInBackground中解析文件。
其他选项是在onPostExecute中运行尽可能多的异步任务。
但是如果文件很大,你应该考虑使用thread / queue-worker模式/服务!
答案 2 :(得分:1)
是的,你正在做的非UI任务必须在doInBackground()方法中完成。 如果你将在主线程中运行的AsyncTask方法中执行一个长时间运行的任务,那么它将为你提供ANR。
答案 3 :(得分:1)
将解析逻辑移动到doinBackground(),如下面的代码。
@Override
protected void onPreExecute()
{
flag = false;
progressCount = 0;
ProgressDialog progressBar = DdownoadProgressBar(context,
progressCount);
progressBar.show();
}
@Override
protected Integer doInBackground(String... urls) {
checkNetworkConnection();
if (connectionFlag) {
downloadFile1();
progressCount = 1;
publishProgress(progressCount);
downloadFile2();
progressCount = 2;
publishProgress(progressCount);
downloadFile3();
progressCount = 3;
publishProgress(progressCount);
downloadFile4();
progressCount = 4;
publishProgress(progressCount);
downloadFile5();
progressCount = 5;
publishProgress(progressCount);
downloadFile6();
progressCount = 6;
publishProgress(progressCount);
downloadflag = true;
}
if (downloadflag) {
try {
parseFile1();
progressCount=7;
publishProgress(progressCount);
parseFile2();
progressCount=8;
publishProgress(progressCount);
parseFile3();
progressCount=9;
publishProgress(progressCount);
parseFile4();
progressCount=10;
publishProgress(progressCount);
parseFile5();
progressCount=11;
publishProgress(progressCount);
parseFile6();
progressCount=12;
publishProgress(progressCount);
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... progress)
{
Log.v(TAG, "In progressUpdate...");
progressBar.setProgress(progressCount);
}
@Override
protected void onPostExecute(Integer progress) {
try {
Log.v(TAG, "Inside onPostExecute....");
progressBar.dismiss();
Toast.makeText(SynchronizeData.this,"Data is successfully downloaded from server.......", Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
答案 4 :(得分:0)
在使用AsyncTask之前,请阅读: Is AsyncTask really conceptually flawed or am I just missing something?
简单地说:从Activity的方法调用AsyncTask在概念上是有缺陷的,因为长操作可能比启动它的活动寿命更长。这样的操作应该是模型的责任(在MVC意义上),在这种情况下,它可能比AsyncTask更严重。