Android - основной текст прогресса загрузки - PullRequest
2 голосов
/ 05 сентября 2011

Я нашел в Интернете фрагмент, показывающий ход загрузки.Я получаю сообщение об ошибке: android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. Моя цель состоит в том, чтобы телефон загрузил файл, а затем по завершении переключился на пункт меню намерений

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.widget.TextView;

public class CheckDownload extends Activity {

/** Called when the activity is first created. */
@Override
protected void onCreate(Bundle SavedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(SavedInstanceState);
    setContentView(R.layout.downloadscreen);
    Thread timer = new Thread() {
        public void run() {
            try {
                // set the download URL, a url that points to a file on the
                // internet
                // this is the file to be downloaded
                URL url = new URL(
                        "http://www.android.com/media/wallpaper/gif/android_logo.gif");

                // create the new connection
                HttpURLConnection urlConnection = (HttpURLConnection) url
                        .openConnection();

                // set up some things on the connection
                urlConnection.setRequestMethod("GET");
                urlConnection.setDoOutput(true);

                // and connect!
                urlConnection.connect();

                // set the path where we want to save the file
                // in this case, going to save it on the root directory of
                // the
                // sd card.
                File SDCardRoot = Environment.getExternalStorageDirectory();
                // create a new file, specifying the path, and the filename
                // which we want to save the file as.
                File file = new File(SDCardRoot, "android_logo.gif");

                // this will be used to write the downloaded data into the
                // file we created
                FileOutputStream fileOutput = new FileOutputStream(file);

                // this will be used in reading the data from the internet
                InputStream inputStream = urlConnection.getInputStream();

                // this is the total size of the file
                int totalSize = urlConnection.getContentLength();
                // variable to store total downloaded bytes
                int downloadedSize = 0;

                // create a buffer...
                byte[] buffer = new byte[1024];
                int bufferLength = 0; // used to store a temporary size of
                                        // the buffer

                // now, read through the input buffer and write the contents
                // to the file
                while ((bufferLength = inputStream.read(buffer)) > 0) {
                    // add the data in the buffer to the file in the file
                    // output stream (the file on the sd card
                    fileOutput.write(buffer, 0, bufferLength);
                    // add up the size so we know how much is downloaded
                    downloadedSize += bufferLength;
                    // this is where you would do something to report the
                    // prgress, like this maybe
                    updateProgress(downloadedSize, totalSize);

                }
                // close the output stream when done
                fileOutput.close();

                // catch some possible errors...
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                Intent chapterMenuIntentObject = new Intent(
                        "com.blah.blah.CHAPTERMENU");
                startActivity(chapterMenuIntentObject);
            }
        }

    };
    timer.start();
}

public void updateProgress(int downloadedSize, int totalSize) {
    int percentage = downloadedSize / totalSize * 100;
    String stringy = "Download Progress: " + percentage + "%";
    TextView textytext = (TextView) findViewById(R.id.downloadscreentextview);
    textytext.setText(stringy);
}

@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    finish();
}

}

Ответы [ 3 ]

4 голосов
/ 05 сентября 2011

Один из простых способов сделать это - использовать функцию runOnUIThread (Runnable). Это функция класса Activity для обновления пользовательского интерфейса. Я считаю, что использовать его удобнее, чем создавать обработчики / сообщения для связи с потоком пользовательского интерфейса. Ваш код может быть изменен на (я еще не тестировал!):

public void updateProgress(int downloadedSize, int totalSize) {
runOnUiThread(new Runnable() {
    public void run() {
        int percentage = downloadedSize / totalSize * 100;
        String stringy = "Download Progress: " + percentage + "%";
    TextView textytext = (TextView) findViewById(R.id.downloadscreentextview);
    textytext.setText(stringy);
}});
}

Дайте мне знать, если у вас есть ошибки.

2 голосов
/ 05 сентября 2011

Вы пытаетесь обновить прогресс от рабочего (или фонового потока), где он не получает ссылку на ваши представления. Это должно быть сделано в потоке пользовательского интерфейса.
Попробуйте использовать AsynTask, облегчая жизнь с потоками.
http://developer.android.com/reference/android/os/AsyncTask.html

или

если вы хотите придерживаться нормальных тем, Проверьте этот код,
http://huuah.com/android-progress-bar-and-thread-updating/
Возможно, вам придется использовать messageHandler, чтобы отправить сообщение на индикатор выполнения, а затем обновить.

0 голосов
/ 05 сентября 2011

Очевидно, что вы должны получить этот тип ошибки, так как текущий поток, который вы работаете, не может обновить GUI. Чтобы обновить графический интерфейс, вы должны понимать концепцию обработчика в Android.* Обработчик в Android.

Я думаю, что вы должны изменить свой код, как показано ниже: -

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;

public class CheckDownload extends Activity {

private TextView textytext;
private int totalSize;
private int downloadedSize = 0;
private TimerThread timer = new TimerThread();

/** Called when the activity is first created. */
@Override
protected void onCreate(Bundle SavedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(SavedInstanceState);
    setContentView(R.layout.downloadscreen);

    timer.start();
}

public void updateProgress(int downloadedSize, int totalSize) {
    int percentage = downloadedSize / totalSize * 100;
    String stringy = "Download Progress: " + percentage + "%";
    TextView textytext = (TextView) findViewById(R.id.downloadscreentextview);
    textytext.setText(stringy);
}

@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    finish();
}

private class TimerThread extends Thread {

    @Override
    public void run() {
        try {
            // set the download URL, a url that points to a file on the
            // internet
            // this is the file to be downloaded
            URL url = new URL(
                    "http://www.android.com/media/wallpaper/gif/android_logo.gif");

            // create the new connection
            HttpURLConnection urlConnection = (HttpURLConnection) url
                    .openConnection();

            // set up some things on the connection
            urlConnection.setRequestMethod("GET");
            urlConnection.setDoOutput(true);

            // and connect!
            urlConnection.connect();

            // set the path where we want to save the file
            // in this case, going to save it on the root directory of
            // the
            // sd card.
            File SDCardRoot = Environment.getExternalStorageDirectory();
            // create a new file, specifying the path, and the filename
            // which we want to save the file as.
            File file = new File(SDCardRoot, "android_logo.gif");

            // this will be used to write the downloaded data into the
            // file we created
            FileOutputStream fileOutput = new FileOutputStream(file);

            // this will be used in reading the data from the internet
            InputStream inputStream = urlConnection.getInputStream();

            // this is the total size of the file
            totalSize = urlConnection.getContentLength();
            // variable to store total downloaded bytes
            downloadedSize = 0;

            // create a buffer...
            byte[] buffer = new byte[1024];
            int bufferLength = 0; // used to store a temporary size of
                                    // the buffer

            // now, read through the input buffer and write the contents
            // to the file
            while ((bufferLength = inputStream.read(buffer)) > 0) {
                // add the data in the buffer to the file in the file
                // output stream (the file on the sd card
                fileOutput.write(buffer, 0, bufferLength);
                // add up the size so we know how much is downloaded
                downloadedSize += bufferLength;
                // this is where you would do something to report the
                // prgress, like this maybe
                handler.sendEmptyMessage(0);
            }
            // close the output stream when done
            fileOutput.close();

            // catch some possible errors...
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            handler.sendEmptyMessage(1);
        }
    }
}

private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {

        switch (msg.what) {

        case 0:
            updateProgress(downloadedSize, totalSize);
            break;
        case 1:
            Intent chapterMenuIntentObject = new Intent(
                    "com.blah.blah.CHAPTERMENU");
            startActivity(chapterMenuIntentObject);
        }

    }
};
}
...