【发布时间】:2020-12-18 21:26:22
【问题描述】:
我使用 Retrofit2 进行文件下载。我无法使用进度值更新 ProgressBar。我得到了进步值。所以不存在问题。当我将进度值设置为未反映在 UI 中的进度条时。
我说的是 RecyclerView Adapter 中的进度条。
下面是我的改造电话, 当点击 RecyclerView 中的一个项目时会调用这个方法。
private void downloadFileFromServer(String otpapi, String userName, String password, String code, String vmFileName, String filePath, String vmFileSize, int position, CircularProgressBar circularProgress) {
GetDataForApiCall getDataForApiCall= RetrofitInstance.getRetrofit(url,otpapi,context).create(GetDataForApiCall.class);
Call<ResponseBody> downloadVoicemail= getDataForApiCall.downloadVoiceMail(userName,password,code,vmFileName);
this.circularProgressBar=circularProgress;
this.circularProgressBar.setIndeterminate(false);
this.circularProgressBar.setProgress(0);
this.circularProgressBar.setMax(100);
this.circularProgressBar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AndroidLogger.log(5,"onClick","circularProgressBar onClick executed!!");
Toast.makeText(context,"cancel clicked",Toast.LENGTH_LONG).show();
cancelDownload = true;
}
});
downloadVoicemail.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
boolean downloadResult = writeResponseBodyToDisk(response.body(),vmFileSize,filePath);
if(downloadResult) {
Toast.makeText(context, "File downloaded", Toast.LENGTH_SHORT).show();
updateVoiceMailFilePath(position, filePath);
updateViews(position);
}else {
deleteVoiceMailFileFromLocalSystem(filePath);
updateViews(position);
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
private boolean writeResponseBodyToDisk( ResponseBody body, String fileSize, String filePath) {
try {
InputStream inputStream = null;
OutputStream outputStream = null;
try {
byte[] fileReader = new byte[8192];
//long fileSize = body.contentLength();
long fileSizeDownloaded = 0;
long lengthOfFile = Long.parseLong( String.format( "%.0f",Double.parseDouble(fileSize )) ) * 1024;
AndroidLogger.log(5,TAG,"filesize"+fileSize + "length of file"+lengthOfFile);
inputStream = body.byteStream();
outputStream = new FileOutputStream(filePath);
while (true) {
int read = inputStream.read(fileReader);
if(cancelDownload){
inputStream.close();
return false;
}
if (read == -1) {
AndroidLogger.log(5,TAG,"-1 value so break");
break;
}
outputStream.write(fileReader, 0, read);
fileSizeDownloaded += read;
if(lengthOfFile >0) {
AndroidLogger.log(5,TAG,"FileSize downloaded"+ fileSizeDownloaded);
int progress = (int) (fileSizeDownloaded * 100 / lengthOfFile);
AndroidLogger.log(5,TAG,"Length of file"+ lengthOfFile);
AndroidLogger.log(5,TAG,"Progress"+ progress);
this.circularProgressBar.setProgress(progress);
update(progress);
}
AndroidLogger.log(5,TAG, "file download: " + fileSizeDownloaded + " of " + fileSize);
}
outputStream.flush();
return true;
} catch (IOException e) {
return false;
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
} catch (IOException e) {
return false;
}
}
我也尝试过 Listener 来更新值,因为改造调用是在其他线程上完成的。因此,对于更新 UI,我使用了没有帮助的侦听器。
我正在使用 Retrofit2 进行 API 调用。因此,为了在所有活动中更新 UI,我使用了接口侦听器。这适用于所有活动。但是当我在 RecyclerView Adapter 类中尝试同样的事情时,无法更新进度条。在调用 api 之前,我已将进度条设置为 0,最大值设置为 100。
以下情况下工作正常,
API 调用前的循环进度条设置为零
下载完成后的圆形进度条将变为勾号
以下不工作,
带有加载指示的圆形进度条
注意:只有在使用 Retrofit2 进行 API 调用时,我才会遇到这个问题。如果我在 Asynctask 中使用普通 HTTPUrlConnection 进行 API 调用,则进度加载工作正常。
我已经通过下面的代码检查了进度更新是否发生在主线程上,
if(Looper.myLooper() == Looper.getMainLooper()) {
circularProgressBar.setProgress(progress);
}
以上if条件满足。尽管进度条没有更新。
下面我也试过了,
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = new Runnable() {
@Override
public void run() {
AndroidLogger.log(5,TAG,"Running on UI thread");
circularProgressBar.setProgress(progress);
}
};
mainHandler.post(myRunnable);
}
我已将它放在 writeResponseBodyToDisk 方法中,在 while 循环中, 但是只调用了两次,进度条没有更新。
我评论了该部分,进度条加载将更改为刻度线。之后,当我尝试下载时,一旦下载完成,就可以在进度条中看到 100% 下载完成。在未反映进度百分比更新之前。
请任何人帮助我解决这个问题。
提前致谢。
【问题讨论】:
标签: java android download retrofit2 android-progressbar