【发布时间】:2014-05-29 10:28:28
【问题描述】:
我必须下载一个带有文件列表的 Json,然后并行下载列表中的文件。我想定期更新ProgressDialog,所以我是这样实现的
- 我创建并显示对话框
-
我开始
AsyncTaskonProgressUpdate接收2个整数,当前进度和最大进度,并更新进度条-
doInBackground- 下载json文件并获取要下载的文件列表
- 创建一个
ThreadPoolExecutor(tpe),带有一个LinkedBlockingQueue<Runnable> - 为每个文件提交一个可运行文件,使用 Apache 将文件下载到磁盘commons-io
FileUtils.copyURLToFile - 执行关机
- 在一段时间内。 tpe.awaitTermination(1, TimeUnit.SECONDS) 定期调用 publishProgress( (int) tpe.getCompletedTaskCount(), tot),更新进度条
- onPostExecute 隐藏和关闭进度条,并管理文件下载
在 AsynTask 中使用 ThreadPoolExecutor 有什么问题吗? 我正在与一位同事讨论,他声称线程管理中可能存在问题,可能会出现死锁,并且可能会给我们未来的版本带来问题
这是代码
public static void syncFiles(...)
{
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
sWakelock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
sWakelock.acquire();
sProgress = new ProgressDialog(context);
sProgress.setCancelable(false);
sProgress.setTitle("MyTitle");
sProgress.setMessage("Sincronizzazione in corso");
sProgress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
sProgress.setIndeterminate(false);
sProgress.show();
sCurrentTask = new AsyncTask<Void, Integer, Manifest>()
{
@Override
protected void onCancelled()
{
if ((sProgress != null) && sProgress.isShowing())
sProgress.dismiss();
if ((sWakelock != null) && sWakelock.isHeld())
sWakelock.release();
};
@Override
protected Manifest doInBackground(Void... params)
{
ArrayList files = getFiles(....)// download the jsonfile, and return the list of files
final String baseurl = ... // get the remote base url
final String baselocal = ... //get the local base path ;
int tot = m.size();
publishProgress(0, tot);
final int MAX_THREADS = Runtime.getRuntime().availableProcessors(); * 4;
ThreadPoolExecutor tpe = new ThreadPoolExecutor(
MAX_THREADS,
MAX_THREADS,
1,
TimeUnit.MINUTES,
new LinkedBlockingQueue<Runnable>()
);
for (final String s: files)
{
tpe.submit(new Runnable()
{
@Override
public void run()
{
try
{
URL remoteUrl = new URL(baseurl + s);
File localUrl = new File(baselocal, s);
FileUtils.copyURLToFile(remoteUrl, localUrl, 60000, 60000);
Log.w(TAG, "Downloaded " + localUrl.getAbsolutePath() + " in " + remoteUrl);
} catch (Exception e)
{
e.printStackTrace();
Log.e(TAG, "download error " + e);
// error management logic
}
}
});
}
tpe.shutdown();
int num = 0;
publishProgress(num, tot);
try
{
while (!tpe.awaitTermination(1, TimeUnit.SECONDS))
{
int n = (int) tpe.getCompletedTaskCount();
Log.w(TAG, "COUTN: " + n + "/" + tot);
if (n != num)
{
num = n;
publishProgress(num, tot);
}
}
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return m;
}
protected void onProgressUpdate(Integer... prog)
{
if (sProgress.getMax() != prog[1]) {
sProgress.setMax(prog[1]);
}
sProgress.setProgress(prog[0]);
}
@Override
protected void onPostExecute(Manifest result)
{
sWakelock.release();
sProgress.hide();
sProgress.dismiss();
// manage results
}
}.execute();
}
【问题讨论】:
-
那你做了什么朋友?我还需要在线程池执行期间更新进度。
标签: android android-asynctask threadpoolexecutor