尝试计时异步任务有点帮助

时间:2011-03-07 16:49:35

标签: android

情况:我想拉一个网络资源(一个文件),显示它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);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

看起来简单的生产者 - 消费者方法就足以满足您的需求。我会有一系列URL指向具有同步访问权限的网络资源。单个AsyncTask足以从队列中弹出单个URL,下载并显示它。如何重新调用任务取决于您:您可以显示下载的资源并同时运行任务,将下载的资源放入某个临时占位符(例如,Drawable成员字段)。有一个定时器,每30秒只将临时资源放入显示器并再次运行下载/缓存任务。

当然,这是一个非常简单的解决方案,如果你的任务没有在30秒的时间范围内完成等,就没有处理案例。

另一种方法是使用一个布尔对象,每隔30秒将其设置为true。您的AsyncTask运行,下载图像和onPostExecute检查,如果之前提到的boolean设置为true,如果是 - 显示图像,将标志设置为false并完成。如果flag为false,则它进入一个休眠的循环,比如200ms并再次检查条件等等。