Frage

I do have a problem with threading:

I have some networt operations (downloads) to do in one of my activities. I wrote a thread for this, so that this happens in the background of my UI thread. But I am doing it wrong in some way, and I do not know how to fix this issue. My code is:

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

Now the problem is, the progress bar appears when loader is almost done. It won't show up before I start loader. I think this is because i join() loader with my UI thread, but I don't know how to circumvent this. I have to wait for loader to finish, because following code will process files downloaded from loader.

I had one idea: I could use a loop like

while(loader.isAlive()){
//doSomething
}

But I am not sure if this would solve my problem.

EDIT:

Ok I will replace my thread by an AsyncTask. This seems to make sense due to the fact that I need the data in the UI in further progression of my programm.

But can somebody explain to me why my progressBar was not shown although I set Visibility to TRUE before starting loader thread? Thank you!

War es hilfreich?

Lösung

You need to perform download operation on background thread and update UI from UI thread.

For this, you can use AsyncTask:

Like this:

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
     }
}

start download:

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

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

Andere Tipps

use async task

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

and here is a full example for AsyncTask

Join() is a blocking call and your progressbar doen't have time to redraw before thread is blocked. Best way for you is to use AsyncTask as was mentioned above, but if you want to do it by yourself don't block your main thread. Use Handler or any other method to post your updates to UI thread.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top