在ProgressDialog之后显示长任务的结果

时间:2011-02-04 21:36:36

标签: android


我有一个运行长任务并返回值的应用程序。任务正在运行时,ProgressDialog显示进度。任务完成后,我想在TextView中显示结果。我在FutureTask中运行任务 我的问题是,如果我尝试获取结果,FutureTask的.get()方法会阻止UI线程,我看不到ProgressDialogTextView显示结果属性)。

我的任务代码(池是ExecutorService):

final FutureTask<String> future = new FutureTask<String>(new Callable<String>() {  
    @Override  
    public String call() {  
        return myLongTask();  
    }  
});  
pool.execute(future);

然后我在updateProgressBar()中拨打Runnable,用ProgressDialog更新Handler

Runnable pb = new Runnable() {  
    public void run() {  
        myUpdateProgressBar();  
    }  
};  
pool.execute(pb);

现在我收到的结果会阻止UI线程阻止ProgressDialog显示:

String result = future.get()

如果我尝试在ProgressDialog解散后将结果放在updateProgressBar()方法内(通过将future作为参数传递),则抛出异常:

  

只有创建视图层次结构的原始线程才能触及其视图。

任何想法如何解决这个问题? (我听说过AsyncTasks,但我无法弄清楚如何使用它们。)

2 个答案:

答案 0 :(得分:2)

您是正确的,您需要AsyncTaskThread / Handler组合才能阻止用户界面。

这两种方法都不是很棘手,并且有一些很好的指南可以解释如何做到这一点。以下是我推荐的一些链接。

答案 1 :(得分:0)

是的,我在实现ExecutorService时遇到类似问题,以下代码阻止了UI线程,需要在一个独立的线程上运行:

String result = future.get()

只需创建一个扩展AsyncTask的类来处理future.get()方法,如下面的代码示例所示:

private class FutureTask extends AsyncTask<Future<String>, Void, String>{

    @Override
    protected PhotoToView doInBackground(Future<String>... params) {
        Future<String> f = params[0];
        try {
            return f.get(30, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (TimeoutException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(String futureResult) {
        super.onPostExecute(futureResult);

        // this method is run on UI thread
        // do something with the result 
        // or simply hide the progress bar 
        // if you had previously shown one.

    }
}

使用以下命令运行未来的主题:

FutureTask ft = new FutureTask();
ft.execute(future);

希望这有帮助。