Попытка получить размер файла при загрузке, но выдает ошибку - PullRequest
1 голос
/ 12 марта 2011
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));

}

Ошибка говорит: только исходный поток, создавший иерархию представлений, может касаться его представлений. я думаю, это означает, что я создаю текстовое представление из одного терада и пытаюсь получить доступ из другого (AsyncTask), но как его получить? Спасибо

EDIT
вот весь код но даже если я отправлю publishProgress(downloadedSize) int value = 10, он всегда выводит в text.setText(String.valueOf(progress)); различные значения, такие как [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;
    }
}

Ответы [ 2 ]

2 голосов
/ 12 марта 2011

Вы правы в своей оценке ошибки.Я предполагаю, что text является TextView объектом, который определен в вашем Activity, и поэтому он создается в потоке пользовательского интерфейса.Код, который выполняется в doInBackground(), выполняется в отдельном потоке.Только поток пользовательского интерфейса может выполнять обновления элементов пользовательского интерфейса, поэтому, когда вы пытаетесь вызвать setText, вы получаете сообщение об ошибке, о котором вы сообщили.

Abhinav также прав, как исправить проблему, как AsyncTaskесть метод, который вы можете вызвать для отправки обновлений из фонового потока в поток пользовательского интерфейса: publishProgress, который вызывает onProgressUpdate().

Добавьте этот метод к вашему AsyncTask:

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

И изменить цикл while в download():

while ( (len1 = in.read(buffer)) != -1 ) 
{
  f.write(buffer,0, len1);
  downloadedSize += len1; 
  publishProgress(downloadedSize);
}
2 голосов
/ 12 марта 2011

Вы можете изменить пользовательский интерфейс, опубликовав прогресс в потоке пользовательского интерфейса.Вызовите publishProgress из doInBackground.Это вызовет onProgressUpdate в AsyncTask, откуда вы можете обновить пользовательский интерфейс.

Вам необходимо определить onProgressUpdate в AsyncTask.http://developer.android.com/reference/android/os/AsyncTask.html#onProgressUpdate(Progress...)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...