线程和UI

时间:2014-05-15 09:12:56

标签: java android multithreading user-interface

我确实遇到线程问题:

我的一项活动中有一些networt操作(下载)。我为此写了一个帖子,所以这发生在我的UI线程的后台。但我在某种程度上做错了,我不知道如何解决这个问题。我的代码是:

private void startDownload(){
    progressBar.setVisibility(View.VISIBLE);
    Downloader loader = new Downloader();
    loader.start();
    try {
        loader.join();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
}

现在的问题是,加载程序即将完成时会出现进度条。在我开始装载之前它不会出现。我想这是因为我用我的UI线程加入()加载器,但我不知道如何规避这个。我必须等待加载程序完成,因为下面的代码将处理从加载程序下载的文件。

我有一个想法:我可以使用像

这样的循环
while(loader.isAlive()){
//doSomething
}

但我不确定这是否能解决我的问题。

修改

好的我将用AsyncTask替换我的线程。这似乎是有道理的,因为我需要UI中的数据进一步推进我的程序。

但是有人可以向我解释为什么我的progressBar没有显示虽然我在启动加载程序线程之前将Visibility设置为TRUE?谢谢!

3 个答案:

答案 0 :(得分:1)

使用异步任务

class MyTask extends AsyncTask...{

onPreExecute(){
    showProgress();
}

doInbackground(){
    //this by itself is a thread so you may need to change the Downloader code
    //it should be normal class, not thread.
    Downloader loader = new Downloader();
    loader.doSomeWork();
    //loader.start();
}

onPostExecute(){
    //you should NOT hide the progress at the end of Downloader()
    hideProgress();
}

这里是AsyncTask的full example

答案 1 :(得分:1)

您需要在后台线程上执行下载操作并从UI线程更新UI。

为此,您可以使用AsyncTask

像这样:

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         // TODO do actual download 

         // publish your download progress
         publishProgress(count);

         return null; // TODO insert your result 
     }

     protected void onProgressUpdate(Integer... progress) {
         // TODO set progress to progressbar
         // update UI
     }

     protected void onPostExecute(Long result) {
         // called when download is complete
         // update UI
     }
}

开始下载:

private void startDownload() {
    progressBar.setVisibility(View.VISIBLE);

    asyncTask = new DownloadFilesTask();
    asyncTask.execute(<urls for download>);
}

答案 2 :(得分:1)

加入()是一个阻止调用,您的进度条在线程被阻止之前没有时间重绘。 最好的方法是使用AsyncTask,如上所述,但如果你想自己做,不要阻止你的主线程。使用Handler或任何其他方法将更新发布到UI线程。