情况:我想拉一个网络资源(一个文件),显示它30秒,然后加载下一个文件。在显示初始文件30秒时,我想预加载下一个文件。
问题:我是否应该使用带锁的并发线程(如链接的阻塞队列?)或处理程序?或者我缺少的东西?
目前我有onCreate调用一个asynctask,它有一个for循环,一次迭代一个文件路径,然后调用下一个asynctask(在for循环内)从该路径下载文件然后在onPostExecute中将文件分配给UI视图。
这有效,但我无法设置第一个文件在UI视图中加载的时间,然后30秒后,下一个文件在UI视图中加载等等...现在它加载文件很好但是第1个可能需要40秒才能显示,第二个25秒和第三个60秒。
(仅供参考,文件大小均匀,加载时间仅为5~15秒)
这是一个通用示例(不可编译):
的onCreate(){ new firstAsynchTask()。execute(filePaths []); }
private class firstAsynchTask extends AsyncTask<String[], Void, Void> {
protected Void doInBackground(String[]... x) {
try {
for(int i = 0; x[0] != null && i < x.length; i++)
{
long startT = System.currentTimeMillis();
if(x[0][i].isFile())
{
SmbFile g = new SmbFile(x[0][i].getPath());
new secondAsynchTask().execute(g);
long TimeNow = (System.currentTimeMillis() - 30000);
if(startT > TimeNow)
{
try {
Thread.sleep(startT - TimeNow);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();}
}
}
if(i == x.length - 1)
{
i = 0;
}
}
return null;
} catch (IOException e) {
// TODO Auto-generated catch block
return null;
}
}
private class SecondAsyncTask extends AsyncTask<File, Integer, Drawable> {
protected File doInBackground(File... x) {
SomeType FileTemp = new File();
try {
long startT = System.currentTimeMillis();
FileTemp = (get streamed file);
long TimeNow = (System.currentTimeMillis() - 30000);
if(startT > TimeNow)
{
Thread.sleep(startT - TimeNow);
return FileTemp;
}
else
{
return FileTemp;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
protected void onPostExecute(File result) {
if(result != null)
{
FileView centerFile = (FileView) findViewById(R.id.FileView1);
centerFile.setFile(result);
}
}
}
答案 0 :(得分:0)
看起来简单的生产者 - 消费者方法就足以满足您的需求。我会有一系列URL指向具有同步访问权限的网络资源。单个AsyncTask足以从队列中弹出单个URL,下载并显示它。如何重新调用任务取决于您:您可以显示下载的资源并同时运行任务,将下载的资源放入某个临时占位符(例如,Drawable成员字段)。有一个定时器,每30秒只将临时资源放入显示器并再次运行下载/缓存任务。
当然,这是一个非常简单的解决方案,如果你的任务没有在30秒的时间范围内完成等,就没有处理案例。
另一种方法是使用一个布尔对象,每隔30秒将其设置为true。您的AsyncTask运行,下载图像和onPostExecute检查,如果之前提到的boolean设置为true,如果是 - 显示图像,将标志设置为false并完成。如果flag为false,则它进入一个休眠的循环,比如200ms并再次检查条件等等。