2016-03-21 8 views
-1

Я только начал изучать, как создать приложение для Android, и я хочу создать приложение для тестирования скорости. Для этого я использовал этот класс: Speed Test libraryполучить результат обратного вызова от doInBackground метод

Я следовал примеру на веб-сайте github, но проблема в том, что я не могу получить результаты, которые будут отображаться в моем пользовательском интерфейсе. Я попытался реализовать интерфейс класса, но это привело к многочисленным ошибкам. Кто-нибудь знает, можно ли это сделать? Я просто хочу, чтобы отобразить результаты на GUI моего приложения ...

Это код, который я использую:

public class SpeedTestTask extends AsyncTask<Void, Void, String> { 

     @Override 
     protected void onPreExecute() { 
      mRunningBar.setVisibility(View.VISIBLE); 
     } 

     @Override 
     protected String doInBackground(Void... params) { 

      SpeedTestSocket speedTestSocket = new SpeedTestSocket(); 
      speedTestSocket.addSpeedTestListener(new ISpeedTestListener() { 

       @Override 
       public void onDownloadPacketsReceived(int packetSize, 
                 float transferRateBitPerSeconds, 
                 float transferRateOctetPerSeconds) { 


        //Log.i(TAG, "download transfer rate : " + transferRateOctetPerSeconds * 1000 + "MBps"); 
        download_result.setText("Download speed : " + transferRateOctetPerSeconds * 1000 + " MBps"); 
       } 

       @Override 
       public void onDownloadError(int errorCode, String message) { 
        Log.i(TAG, "There was error " + errorCode + " Message: " + message); 
       } 

       @Override 
       public void onUploadPacketsReceived(int packetSize, 
                float transferRateBitPerSeconds, 
                float transferRateOctetPerSeconds) { 
        download_result.setText("Upload speed (upload) : " + transferRateOctetPerSeconds * 1000 + " MBps"); 
       } 

       @Override 
       public void onUploadError(int errorCode, String message) { 
        // Log.i(TAG, "Upload error " + errorCode + " occured with message : " + message); 
        download_result.setText("Upload error (upload) " + errorCode + " Message: " + message); 
       } 

       @Override 
       public void onDownloadProgress(int percent) { 
       } 

       @Override 
       public void onUploadProgress(int percent) { 
       } 

      }); 

      speedTestSocket.startDownload("ipv4.intuxication.testdebit.info", 80,"/fichiers/10Mo.dat"); 
      speedTestSocket.startUpload("1.testdebit.info", 
        80, "/", 10000000); 



      return null; 
     } 

     @Override 
     protected void onPostExecute(String result) { 
      // download_result.setText(result); 
      mRunningBar.setVisibility(View.GONE); 

     } 
    } 
+0

Проверьте это http://stackoverflow.com/questions/14253421/how-one-interface-can-be-used-for-different-background-android-tasks/14376233#14376233 – Pragnani

ответ

1

все, что вы написали в doInBackground выполняется в потоке без пользовательского интерфейса. Если вы хотите обновить элементы пользовательского интерфейса, вы должны сделать это в onPostExecute, который выполняется в потоке пользовательского интерфейса.

EDIT

Если вам необходимо обновить элементы пользовательского интерфейса из любого другого потока, то вы можете сделать следующее

runOnUiThread(new Runnable() { 
    public void run() { 
     download_result.setText("Download speed : " + transferRateOctetPerSeconds * 1000 + " MBps"); 

    } 
}); 

РЕДАКТИРОВАНИЕ 2

я исправлюсь. Вы также можете использовать onProgressUpdate(), как некоторые пользователи, упомянутые здесь, для управления элементами пользовательского интерфейса. Я думаю, с помощью onProgressUpdate было бы лучшим вариантом, чем то, что я предложил здесь

+0

Спасибо за быстрый ответ @MuchOverflow. Итак, я просто переместил свой код в onPostExecute? – jureispro

+0

В вашем случае я не думаю, что это возможно, так как вам нужно выполнять сетевые операции. Пожалуйста, уточните мой обновленный ответ –

+1

'вы должны сделать это в onPostExecute' << это на самом деле не так. Вы можете обновить 'Просмотры' в' onProgressUpdate (Прогресс ... значения) ', который вызывается в основном потоке – Droidman

2

цитата из документации AsyncTask, об обновлении показателей прогресса:

onProgressUpdate (Прогресс ...), вызывается в потоке пользовательского интерфейса после вызова publishProgress (Прогресс ...). Время выполнения не определено. Этот метод используется для отображения любой формы прогресса в пользовательском интерфейсе, пока фоновое вычисление все еще выполняется. Например, его можно использовать для анимации индикатора выполнения или отображения журналов в текстовом поле.

Я думаю, что это будет идеально подходит для вашего случая использования.

1

сделать весь ваш запрос в Интернете в doInBackground и обновить макет ui в постэкспорте. Все preExcute, postExcute и onProgress находятся в основном потоке (ui thread), где вы можете обновлять интерфейс.

0

Обратные вызовы publishProgress и onProgressUpdate - это то, что вы, вероятно, ищете. Пример с загрузкой только:

@Override 
public void onDownloadProgress(int percent) { 
    SpeedTestTask.this.publishProgress(percent); 
} 

переопределять значение onProgressUpdate дозвона AsyncTask:

@Override 
protected void onProgressUpdate(Integer... values) { 
    super.onProgressUpdate(values); 
     // update your Views here 
} 

Если вы хотите опубликовать как скачать и прогресс загрузки, вам нужен способ для вашего onProgressUpdate обратного вызова знать какой вид прогресса обновляется. Поскольку для этого параметра требуется массив (Integer... values), вы можете использовать другой индекс для каждого конкретного вида прогресса.Пример:

@Override 
public void onDownloadProgress(int percent) { 
    // using the index 0 for download 
    SpeedTestTask.this.publishProgress(percent, -1); 
} 

Другой обратный вызов:

@Override 
public void onUploadProgress(int percent) { 
// using the index 1 for upload 
SpeedTestTask.this.publishProgress(-1, upload); 
} 

Тогда:

@Override 
protected void onProgressUpdate(Integer... values) { 
    super.onProgressUpdate(values); 
    if(values[0] != -1) 
     // download 
    else 
     //upload 
} 

EDIT: так как я не знаю, является ли значение -1 может быть передано обратного вызова по в библиотеке я взял это в качестве примера. Вероятно, безопаснее использовать некоторую другую константу, чтобы указать, что в соответствующем индексе нет значения.

+0

Спасибо за ваш комментарий @Droidman. Я пробовал ваш код, но я получил ошибку на «onDownloadProgress» и на «onUploadProgress». В нем говорится, что ASyncTask не может быть применен для массива int (int []) – jureispro

+0

@jureispro для моего плохого, я обновил код. Примечание: ваша параметризация 'AsyncTask' теперь должна выглядеть так:' extends AsyncTask ', иначе она не будет работать – Droidman

+0

спасибо вам за все ваши. Я импигментировал ваш код, и он работает. Я получаю загрузку. Проблема в том, что я хочу скорость загрузки. Можно ли использовать методы onDownloadPacketsReceived и onUploadPacketsReceived – jureispro

0

Не обновляйте элемент пользовательского интерфейса в фоновом потоке. AsyncTask: onOpreExecute -> Работает на основном потоке.doInBackground -> Работает на рабочем потоке. onPostExecute -> Работает в основном потоке.

Поскольку вы обновляете

download_result.setText ("Ошибка при загрузке (загрузить)" + ERRORCODE + "сообщение:" + сообщение);

in doInBackground, ваше приложение выйдет из строя, если у вас есть какое-то исключение.

Сделайте это в главной теме.

Смежные вопросы