1
private class DownloadLargeFileTask extends AsyncTask<Void, Void, Void> 
{
    private final ProgressDialog dialog;

    public DownloadLargeFileTask(ProgressDialog dialog) {
         this.dialog = dialog;
    }

    protected void onPreExecute() {
        dialog.show();
    }


    protected void onPostExecute(Void unused) {
        dialog.dismiss();
    }

    @Override
    protected Void doInBackground(Void... arg0) {
        download();
        return null;
    }
}

private void download ()
{
    try 
    {
        long startTime = System.currentTimeMillis();

        URL u = new URL("http://mds.podfm.ru/188/download/040_Sergejj_Palijj_-_Karantin_CHast_2.mp3");
        HttpURLConnection c = (HttpURLConnection) u.openConnection();

        c.setRequestMethod("GET");
        c.setDoOutput(true);
        c.connect();
        FileOutputStream f = new FileOutputStream(new File("/sdcard/","my.mp3"));

        InputStream in = c.getInputStream();

        byte[] buffer = new byte[1024];
        int len1 = 0;
        int downloadedSize = 0;
        while ( (len1 = in.read(buffer)) != -1 ) 
        {
          f.write(buffer,0, len1);
          downloadedSize += len1; 
          ReturnDownloadedBytes(downloadedSize);
        }
        f.close();
        Log.d("ImageManager", "download ready in" + ((System.currentTimeMillis() - startTime) / 1000) + " sec");
    }
    catch (IOException e)
    {
        Log.d("ImageManager", "Error" + ((System.currentTimeMillis()) / 1000) + e + " sec");
    }
}

private void ReturnDownloadedBytes(int size)
{
    text.setText(String.valueOf(size));

}

Error says: Only the original thread that created a view hierarchy can touch its views. i think this means that i create textview from one therad and trying to get access from another one (AsyncTask) but how to get it? Thanks

EDIT
here is the all code. but even if i send in publishProgress(downloadedSize) int value = 10 it alwys outputs in text.setText(String.valueOf(progress)); different values like [Ljava.lang.float;@43ed62f78

public class list extends Activity {

private TextView text;



@Override
public void onCreate(Bundle icicle)
{
    super.onCreate(icicle);
    setContentView(R.layout.main);

    text = (TextView)findViewById(R.id.result);
}

public void selfDestruct(View view) {

    ProgressDialog dialog = new ProgressDialog(this);
    dialog.setMessage("????????. ?????...");
    new DownloadLargeFileTask(dialog).execute();

}


private class DownloadLargeFileTask extends AsyncTask<Void, Integer, Void> 
{
    private final ProgressDialog dialog;

    public DownloadLargeFileTask(ProgressDialog dialog) {
         this.dialog = dialog;
    }

    protected void onPreExecute() {
        dialog.show();
    }


    protected void onPostExecute(Void unused) {
        dialog.dismiss();
    }

    protected void onProgressUpdate(Integer...progress) {

        text.setText(String.valueOf(progress));

    }

    @Override
    protected Void doInBackground(Void... arg0) {
        try 
        {
            long startTime = System.currentTimeMillis();

            URL u = new URL("http://mds.podfm.ru/188/download/040_Sergejj_Palijj_-_Karantin_CHast_2.mp3");
            HttpURLConnection c = (HttpURLConnection) u.openConnection();

            c.setRequestMethod("GET");
            c.setDoOutput(true);
            c.connect();
            FileOutputStream f = new FileOutputStream(new File("/sdcard/","my.mp3"));

            InputStream in = c.getInputStream();

            byte[] buffer = new byte[1024];
            int len1 = 0;
            int downloadedSize = 10;
            while ( (len1 = in.read(buffer)) != -1 ) 
            {
              f.write(buffer,0, len1);
              //downloadedSize += len1; 
              **publishProgress(downloadedSize);**
            }
            f.close();
            Log.d("ImageManager", "download ready in" + ((System.currentTimeMillis() - startTime) / 1000) + " sec");
        }
        catch (IOException e)
        {
            Log.d("ImageManager", "Error" + ((System.currentTimeMillis()) / 1000) + e + " sec");
        }
        return null;
    }
}
dave.c
  • 10,910
  • 5
  • 39
  • 62
SERG
  • 3,907
  • 8
  • 44
  • 89

2 Answers2

2

You can change the UI by publishing the progress to the UI thread. Call publishProgress from doInBackground. This will call onProgressUpdate in your AsyncTask from where you can update the UI.

You will have to define onProgressUpdate in your AsyncTask. http://developer.android.com/reference/android/os/AsyncTask.html#onProgressUpdate(Progress...)

Abhinav
  • 38,516
  • 9
  • 41
  • 49
2

You are correct in your assessment of the error. I'm assuming that text is a TextView object that is defined in your Activity, and as such it is created in the UI thread. The code that runs within doInBackground() runs in a separate thread. Only the UI thread can perform updates to UI elements, so when you try to call setText you get the error message that you reported.

Abhinav is also correct in how to fix the issue, as AsyncTask has a method that you can call to send updates from the background thread to the UI thread: publishProgress, which calls onProgressUpdate().

Add this method to your AsyncTask:

@Override
protected void onProgressUpdate(Integer... integer){
    text.setText(integer[0].toString());
}

And change the while loop in download():

while ( (len1 = in.read(buffer)) != -1 ) 
{
  f.write(buffer,0, len1);
  downloadedSize += len1; 
  publishProgress(downloadedSize);
}
dave.c
  • 10,910
  • 5
  • 39
  • 62
  • can you explain me what does "URL, Integer, Long" means in this " private class DownloadFilesTask extends AsyncTask" and what is the differense in order of this params/. thanks – SERG Mar 12 '11 at 18:19
  • and when i call text.setText(String.valueOf(progress)); in result i get in TextView something like [Ljava.lang.float;@43ed62f78 - what does this means? – SERG Mar 12 '11 at 18:40
  • @SERG check the [documentation](http://developer.android.com/reference/android/os/AsyncTask.html), they are `Params`, `Progress` and `Result`. I'd need to see more of your code to diagnose the other issue. – dave.c Mar 12 '11 at 19:51
  • @SERG Please don't post a new question as an answer to an existing question. That said, compare my code above with yours, you can see that the parameter of `onProgressUpdate()` is an *array* of values, which is why I use `integer[0].toString()` to get the desired value. When you use `String.valueOf(progress)` you will just the the memory location, as `progress` is an *array*. Please use the approach I provided in my answer. – dave.c Mar 13 '11 at 12:40