java - 为什么一旦达到一定数量,进度就会减少?
问题描述
我正在从 Firebase Firestore 下载一个包含文件 URL 的文件。文件大小超过 100 MB。我正在使用 Asyctask 执行代码,但是一旦达到某个值,它就会减少。
我尝试获取进度的绝对值,但它仍然减少了。
public static final class DownloadGameTask extends AsyncTask<String, Integer, String> {
private Context mContext;
DownloadGameTask(Context context) {
mContext = context;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
//Kaylangan ng ID for Oreo above
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//Kapag oreo or above ang verion ng phone
mChannel = new NotificationChannel(CHANNEL_ID, name, NotificationManager.IMPORTANCE_DEFAULT);
mChannel.setVibrationPattern(new long[]{0});
mChannel.enableVibration(true);
notification = new NotificationCompat.Builder(mContext, CHANNEL_ID)
.setSmallIcon(R.drawable.download_icon)
.setProgress(0, 0, false);
notificationManager.createNotificationChannel(mChannel);
}
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
Log.d("Avery", values[0] + "");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mChannel.setVibrationPattern(new long[]{0});
mChannel.enableVibration(true);
notification.setProgress(100, values[0], false);
//notificationManager.createNotificationChannel(mChannel);
notificationManager.notify(NOTIFY_ID, notification.build());
}
}
@Override
protected String doInBackground(String... strings) {
Log.d("Avery", "Starting Async");
File gameFile;
//final String path = Environment.getExternalStorageDirectory() + "//Download//" + "//ChamberDownloads//Books/" + "/" + strings[0] + "//" + strings[0] + ".apk";
final String absolutePath = Environment.getExternalStorageDirectory().getAbsolutePath();
final String fileSize = strings[1]; //Eto yung galing sa params ng Asynctask
Log.d("Avery", Environment.DIRECTORY_DOWNLOADS);
int count;
try {
URL url = new URL(strings[0]);
URLConnection connection = url.openConnection();
gameFile = new File(absolutePath, "Game" + ".apk");
if (!gameFile.exists()) {
gameFile.getParentFile().mkdirs();
gameFile.createNewFile();
Log.d("Avery", "APK does not exists");
} else {
Log.d("Avery", "APK exists");
}
int lengthOfFile = connection.getContentLength();
Log.d("Avery", "Length of file: " + lengthOfFile);
InputStream inputStream = new BufferedInputStream(url.openStream());
OutputStream outputStream = new FileOutputStream(gameFile);
byte data[] = new byte[4096]; ///
long total = 0;
int progress = 0;
while ((count = inputStream.read(data)) != -1) {
Math.abs(total += count);
int progress_temp = Math.abs((int) (total * 100) / Integer.parseInt(fileSize));
if(progress_temp%10 == 0 && progress != progress_temp){
progress = progress_temp;
Log.v("Avery", "total = "+progress);
}
publishProgress(progress);
// Log.d("Avery", String.valueOf(total));
outputStream.write(data, 0, count);
}
outputStream.flush();
outputStream.close();
inputStream.close();
} catch (Exception e) {
Log.e("Avery", e.getMessage());
}
return null;
}
}
我希望输出是进步永远不会减少。
解决方案
你确实溢出了一个int
.
(int) (total * 100)
一旦total
超过 21,474,836 就会溢出。此时,乘法的结果变得大于 (2^31 - 1),这是可以用 a 表示的最大正值int
。由于您将long
结果转换为int
,因此值会换行,并且符号可以翻转。
要修复,只需更改您的铸造顺序,以便在以下位置进行计算longs
:
int progress_temp = Math.abs((int) ((total * 100) / Integer.parseInt(fileSize)));
推荐阅读
- javascript - 如何制定可以滚动数月和数年的日期
- julia - Julia 多重调度入门
- graphql - 发送 GraphQL 获取请求时收到 400 错误
- javascript - 在 for 循环开始时,IE 中的调用对象无效
- laravel - 使用 vue 将 1 和 0 替换为渲染表中的字符串
- sql - 如何根据计算对plsql中的数据进行分组并从中绘制图表?
- xamarin.forms - 从 PC 部署到自身时 Xamarin.Forms UWP 中的部署错误
- php - 使用两个参数sql在mysql中添加相同的值
- android - 我想从抽屉按钮调用 MainActivity 的一个函数
- autodesk-forge - 将按钮添加到 Forge 查看器