我刚开始学习如何创建android应用程序,我想构建速度测试应用程序。为此,我使用了这个课程:Speed Test library
我在github网站上关注了示例,但问题是我无法在我的UI上显示结果。我试图实现类接口,但它导致了许多错误。有人知道可以做到吗?我只是想在我的应用程序的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 :(得分:2)
AsyncTask文档中有关更新进度指示器的引用:
onProgressUpdate(Progress ...),在调用publishProgress(Progress ...)后在UI线程上调用。执行的时间是不确定的。此方法用于在后台计算仍在执行时显示用户界面中的任何形式的进度。例如,它可用于为进度条设置动画或在文本字段中显示日志。
我认为这对您的用例非常理想。
答案 1 :(得分:1)
在doInBackground
中编写的任何内容都是在非UI线程中执行的。如果要更新UI元素,则必须在UI线程中执行的onPostExecute
中执行此操作。
修改强>
如果您必须从任何其他线程更新UI元素,那么您可以执行以下操作
runOnUiThread(new Runnable() {
public void run() {
download_result.setText("Download speed : " + transferRateOctetPerSeconds * 1000 + " MBps");
}
});
编辑2
我的立场得到了纠正。您也可以使用onProgressUpdate()
作为此处提到的一些用户来操作UI元素。我认为使用onProgressUpdate
将是比我在此处建议的更好的选择
答案 2 :(得分:1)
在doInBackground中提出所有的互联网请求,并在postexcute中更新你的布局ui。 preExcute,postExcute和onProgress都在主线程(ui线程)中,您可以在其中更新UI。
答案 3 :(得分:0)
publishProgress
和onProgressUpdate
回调是您可能正在寻找的。仅下载示例:
@Override
public void onDownloadProgress(int percent) {
SpeedTestTask.this.publishProgress(percent);
}
覆盖onProgressUpdate
的<{1}}回调:
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);
}
编辑:因为我不知道值-1是否可以通过库传递给你的回调,所以我把它作为一个例子。可能使用其他常量表示相应索引没有值更安全。
答案 4 :(得分:0)
不要更新后台线程中的任何UI元素。 AsyncTask:onOpreExecute - &gt;在主thread.doInBackground上运行 - &gt;在工作线程上运行。 onPostExecute - &gt;在主线上运行。
由于您正在更新
download_result.setText(“上传错误(上传)”+ errorCode +“消息:”+消息);
在doInBackground中,一旦你遇到异常,你的应用程序就会崩溃。在主线程中执行。