Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/194.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 线程和用户界面_Java_Android_Multithreading_User Interface - Fatal编程技术网

Java 线程和用户界面

Java 线程和用户界面,java,android,multithreading,user-interface,Java,Android,Multithreading,User Interface,我确实有线程问题: 我有一些网络操作(下载)要在我的一个活动中执行。我为此写了一个线程,所以这发生在我的UI线程的后台。但我在某种程度上做错了,我不知道如何解决这个问题。我的代码是: private void startDownload(){ progressBar.setVisibility(View.VISIBLE); Downloader loader = new Downloader(); loader.start(); try { loa

我确实有线程问题:

我有一些网络操作(下载)要在我的一个活动中执行。我为此写了一个线程,所以这发生在我的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
}
但我不确定这是否能解决我的问题

编辑:

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

但有人能向我解释为什么在启动加载程序线程之前,虽然我将可见性设置为TRUE,但我的progressBar没有显示?谢谢大家!

使用异步任务

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();
}

这里是一个异步任务,您需要在后台线程上执行下载操作,并从UI线程更新UI

为此,您可以使用:

像这样:

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
     }
}
私有类下载文件任务扩展异步任务{
受保护的长doInBackground(URL…URL){
//TODO做实际下载
//发布您的下载进度
出版进度(计数);
return null;//TODO插入结果
}
受保护的void onProgressUpdate(整数…进度){
//TODO将进度设置为progressbar
//更新用户界面
}
受保护的void onPostExecute(长结果){
//下载完成时调用
//更新用户界面
}
}
开始下载:

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

    asyncTask = new DownloadFilesTask();
    asyncTask.execute(<urls for download>);
}
private void startDownload(){
progressBar.setVisibility(View.VISIBLE);
asyncTask=新的下载文件任务();
asyncTask.execute();
}
Join()是一个阻塞调用,在线程被阻塞之前,progressbar没有时间重新绘制。
对您来说,最好的方法是使用上面提到的AsyncTask,但如果您想自己完成它,请不要阻塞主线程。使用Handler或任何其他方法将更新发布到UI线程。

为什么不使用Asynctask?join是一个阻塞调用。您正在让UI线程等待下载程序完成尝试使用AsyncTask@BirajZalavadia为什么AsyncTask必须是每个线程问题的答案?因为它易于使用且可读性更强。