Java 线程和用户界面
我确实有线程问题: 我有一些网络操作(下载)要在我的一个活动中执行。我为此写了一个线程,所以这发生在我的UI线程的后台。但我在某种程度上做错了,我不知道如何解决这个问题。我的代码是: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
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必须是每个线程问题的答案?因为它易于使用且可读性更强。