Реализация индикатора выполнения с методом записи dataoutputstream

Можно ли включить горизонтальную полосу выполнения в следующий код? Я думал os AsyncTask, но потом понял, что не могу передать целочисленное значение методу ProgressUpdate () внутри doInBackground (). Пожалуйста помоги!

public void sendFileDOS() throws FileNotFoundException {
    runOnUiThread( new Runnable() {
          @Override
          public void run() {
              registerLog("Sending. . . Please wait. . .");
          }
        });
    final long startTime = System.currentTimeMillis();
    final File myFile= new File(filePath); //sdcard/DCIM.JPG
    byte[] mybytearray = new byte[(int) myFile.length()];
    FileInputStream fis = new FileInputStream(myFile);  
    BufferedInputStream bis = new BufferedInputStream(fis);
    DataInputStream dis = new DataInputStream(bis);
    try {
        dis.readFully(mybytearray, 0, mybytearray.length);
        OutputStream os = socket.getOutputStream();
        //Sending file name and file size to the server  
        DataOutputStream dos = new DataOutputStream(os);     
        dos.writeUTF(myFile.getName());     
        dos.writeLong(mybytearray.length);     
        dos.write(mybytearray, 0, mybytearray.length);     
        dos.flush();

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    runOnUiThread( new Runnable() {
          @Override
          public void run() {
              long estimatedTime = (System.currentTimeMillis() - startTime)/1000;
              registerLog("File successfully sent");
              registerLog("File size: "+myFile.length()/1000+" KBytes");
              registerLog("Elapsed time: "+estimatedTime+" sec. (approx)");
              registerLog("Server stopped. Please restart for another session.");
              final Button startServerButton=(Button)findViewById(R.id.button1);
              startServerButton.setText("Restart file server");
          }
        });
}

person Vinit Shandilya    schedule 24.06.2013    source источник
comment
stackoverflow.com/q/11887149/1715716   -  person Gauthier Boaglio    schedule 24.06.2013


Ответы (3)


Вы можете использовать AsyncTask, который получает такой индикатор выполнения:

public abstract class BaseTask extends AsyncTask<String, Integer, String> 
{   
    private ProgressBar    m_progressBar;

    protected BaseTask(ProgressBar p)
    {
        m_progressBar = p;
    }

    @Override
    protected void onPreExecute()
    {   
        if (m_progressBar != null)
        {
            m_progressBar.setProgress(0);
        }
    }

    @Override
    protected void onPostExecute(String result)
    {   
        if (m_progressBar != null)
            m_progressBar.setVisibility(ProgressBar.GONE);
    }

    public void OnProgress(int prog)
    {
        if (m_progressBar != null)
        {
            m_progressBar.setProgress(prog);
        }
    }
}

Чтобы добавить индикатор выполнения в ваш xml:

<ProgressBar
 android:id="@+id/progressBar"
 style="?android:attr/progressBarStyleHorizontal"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:layout_margin="10dp" />

Чтобы инициализировать индикатор выполнения в коде:

ProgressBar p = (ProgressBar)findViewById(R.id.progressBar);
p.setVisibility(ProgressBar.VISIBLE);
p.setMax(100);
person Kostia    schedule 24.06.2013

Для тех, кто сталкивается с подобными проблемами, вот рабочий метод передачи файлов с использованием потока вывода данных. Основная идея заключалась в том, чтобы разбить файл на несколько частей (я разделил на 100 частей) и записать в DOS в цикле while. Используйте счетчик циклов для обновления индикатора выполнения. Обязательно обновите индикатор выполнения в основном потоке пользовательского интерфейса, иначе приложение выйдет из строя. Вот код:

public void sendFileDOS() throws FileNotFoundException {
    runOnUiThread( new Runnable() {
          @Override
          public void run() {
              registerLog("Sending. . . Please wait. . .");
          }
        });
    final long startTime = System.currentTimeMillis();
    final File myFile= new File(filePath); //sdcard/DCIM.JPG
    byte[] mybytearray = new byte[(int) myFile.length()];
    FileInputStream fis = new FileInputStream(myFile);  
    BufferedInputStream bis = new BufferedInputStream(fis);
    DataInputStream dis = new DataInputStream(bis);
    try {
        dis.readFully(mybytearray, 0, mybytearray.length);
        OutputStream os = socket.getOutputStream();
        //Sending file name and file size to the server  
        DataOutputStream dos = new DataOutputStream(os);     
        dos.writeUTF(myFile.getName());     
        dos.writeLong(mybytearray.length);     
        int i = 0;
        final ProgressBar myProgBar=(ProgressBar)findViewById(R.id.progress_bar);
        while (i<100) {
            dos.write(mybytearray, i*(mybytearray.length/100), mybytearray.length/100);
            final int c=i;
            runOnUiThread( new Runnable() {
                  @Override
                  public void run() {
                      registerLog("Completed: "+c+"%");
                      myProgBar.setProgress(c);
                  }
                });
            i++;
        }    
        dos.flush();

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    runOnUiThread( new Runnable() {
          @Override
          public void run() {
              long estimatedTime = (System.currentTimeMillis() - startTime)/1000;
              registerLog("File successfully sent");
              registerLog("File size: "+myFile.length()/1000+" KBytes");
              registerLog("Elapsed time: "+estimatedTime+" sec. (approx)");
              registerLog("Server stopped. Please restart for another session.");
              final Button startServerButton=(Button)findViewById(R.id.button1);
              startServerButton.setText("Restart file server");
          }
        });
}

Ваше здоровье! :)

person Vinit Shandilya    schedule 24.06.2013
comment
отлично выглядит, могу ли я обновить значение, например, вместо i ++ сделать его больше, например, i + = 25, чтобы оно было разделено на 4 части? - person Mihae Kheel; 03.04.2020

Я не могу передать целочисленное значение методу ProgressUpdate () внутри doInBackground ()

Да, ты можешь !

Используйте publishProgress с обязательными параметрами внутри doInBackground для запуска onProgressUpdate:

final class MyTask extends AsyncTask<Void, Integer, Void> {

    private final ProgressBar progress;

    public MyTask(final ProgressBar progress) {
        this.progress = progress;
    }

    @Override
    protected void onPreExecute() {
        progress.setMax(100);
    }

    @SuppressWarnings("unchecked")
    @Override
    protected Void doInBackground(final Void... params) {
        ...
        int progress_val = // What ever you want
        publishProgress(progress_val);  // Here we trigger 'onProgressUpdate' 
                                        // with the updated integer as parameter
        return null;
    }

    @Override
    protected void onProgressUpdate(final Integer... values) {
        progress.incrementProgressBy(values[0]);  // Here we update the bar
    }

    @Override
    protected void onPostExecute(final Void result) {
        parent.finish();
    }
}

ИЗМЕНИТЬ:

Предложение писать блоками:

int i = 0;
int offset = 0;
int buflen = mybytearray.length/100;
while (i<100) {
    dos.write(mybytearray, offset, buflen);
    offset += buflen;
    i++;
}
dos.write(mybytearray, offset, mybytearray.length%100);
person Gauthier Boaglio    schedule 24.06.2013
comment
Большое спасибо, Голгаут! Извините за один глупый вопрос: dos.write (mybytearray, 0, mybytearray.length) записывает файл за один раз. Как я могу выбрать промежуточное значение, чтобы увеличить индикатор выполнения на это значение? Не могли бы вы изменить мой код? - person Vinit Shandilya; 24.06.2013
comment
Пишите в цикле, например, блоками по mybytearray.length/100 (! Это целочисленное деление, поэтому будет пауза). Затем на каждой итерации увеличивайте ... Не забудьте записать остаток сразу после завершения цикла (rest=mybytearray.length%100). - person Gauthier Boaglio; 24.06.2013
comment
Позвольте мне изменить свой код, и я вернусь к вам! Спасибо еще раз. :) - person Vinit Shandilya; 24.06.2013
comment
Привет, Голгаут! Как вы подсказали, я попытался это реализовать. См. Раздел «Обновление» выше. Не могли бы вы помочь? Я думаю, что это случай превышения лимита данных .. - person Vinit Shandilya; 24.06.2013
comment
Я думаю, что ваше смещение было неправильным ... Я сделал предложение в конце своего ответа. Если приложение вылетает из строя, возможно, где-то в вашем logcat возникло исключение. В таком случае, пожалуйста, покажите его мне (отредактировав свой вопрос, а не мой ответ;) - person Gauthier Boaglio; 24.06.2013
comment
Крайне сожалею об этом! Я все еще новичок в stackoverflow! Кстати, я решил свою проблему. Я удалил блок отдыха, и код начал работать как шарм! Я не могу понять причину, но он работает нормально (я проверил и перепроверил). Но остается только одна проблема! Я не могу передать файл размером более 65 МБ. Любая работа? Пожалуйста, найдите мой обновленный код в разделе редактирования. Также добавлен индикатор выполнения! Спасибо за вашу помощь! :) - person Vinit Shandilya; 24.06.2013
comment
Рад слышать! Кстати: лучше придумайте ответ на свой вопрос и удалите часть «редактировать» из своего вопроса, пожалуйста. Это более понятно для всех, кто хочет получить от этого вдохновение. Спасибо;) - и я могу проголосовать за то, что поделился ... - person Gauthier Boaglio; 24.06.2013