Threading and UI



我确实有一个线程问题:

在我的一个活动中有一些网络操作(下载)要做。我为此写了一个线程,让它在UI线程的后台发生。但我做错了在某些方面,我不知道如何解决这个问题。我的代码是:

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

现在的问题是,进度条出现时,加载程序几乎完成。在我启动加载程序之前它不会显示出来。我认为这是因为我加入()加载器与我的UI线程,但我不知道如何规避这一点。我必须等待loader完成,因为下面的代码将处理从loader下载的文件。

我有一个想法:我可以使用像 这样的循环
while(loader.isAlive()){
//doSomething
}

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

编辑:

好吧,我会用AsyncTask代替我的线程。这似乎是有道理的,因为在程序的进一步发展中,我需要UI中的数据。

但是有人可以向我解释为什么我的进度条没有显示,虽然我设置可见性为TRUE开始加载程序线程之前?谢谢你!

您需要在后台线程执行下载操作,并从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>);
}

使用异步任务

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

的完整示例

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

相关内容

  • 没有找到相关文章

最新更新