gpt4 book ai didi

android - 在 AsyncTask 中的 Honeycomb 上下载大文件(> 100mb)会减慢 UI,可能是因为 GC?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:08:04 33 4
gpt4 key购买 nike

我的一个 Activity 中有一个名为 DownloadFileAsyncTask 的私有(private)内部类。我附上了它:

private class DownloadFileAsyncTask extends AsyncTask<URL, Integer, Boolean> {
private static final String TAG = "DownloadFileAsyncTask";

@Override
protected void onPreExecute() {
WifiManager manager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
mWifiLock = manager.createWifiLock("wifilock");

mWifiLock.acquire();
}

@Override
protected Boolean doInBackground(URL... params) {
try {
URLConnection urlConnection = params[0].openConnection();
urlConnection.connect();

InputStream in = urlConnection.getInputStream();
FileOutputStream out = openFileOutput("archive.zip", Context.MODE_PRIVATE);

int fileSize = urlConnection.getContentLength();
if (fileSize == 0) {
return false;
}

int downloadedSize = 0;

byte[] data = new byte[1024];
int count = 0;

while ((count = in.read(data)) != -1) {
if (isCancelled()) {
Log.d(TAG, "Download cancelled.");

out.close();
in.close();
return false;
}

out.write(data, 0, count);
downloadedSize += count;

publishProgress(downloadedSize, fileSize);
}

out.close();
in.close();
}
catch (Exception ex) {
Log.e(TAG, "doInBackground()", ex);

return false;
}

return true;
}

@Override
protected void onProgressUpdate(Integer... values) {
int downloadedSize = values[0];
int fileSize = values[1];

int progressPercent = ((int) ((downloadedSize / (float) fileSize) * 100));

mDownloadButton.setText(String.format("%.1f MB", downloadedSize / 1048576f));
mProgressBar.setProgress(progressPercent);
}

@Override
protected void onPostExecute(Boolean result) {
}

@Override
protected void onCancelled() {
mWifiLock.release();
}
}

此代码有效。该文件已下载,我的 ProgressBar 已正确更新。我还有一个取消按钮,用户可以按下它来关闭下载。这也有效,但是,当我按下按钮时,按下按钮需要几秒钟才能注册(我正在硬件上测试)。当我在下载过程中查看 logcat 时,我看到发生了很多垃圾收集。事实上,它似乎是不变的。我知道 GC 会导致 UI 延迟,我的理论是这就是这里发生的事情。有谁之前经历过这个吗?有没有更好的方法来执行文件下载?

编辑:

在主循环的每次迭代结束时调用 publishProgress() 会导致延迟。以下是用于解决此问题的 doInBackground() 更新代码:

@Override
protected Boolean doInBackground(URL... params) {
try {
URLConnection urlConnection = params[0].openConnection();
urlConnection.connect();

BufferedInputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedOutputStream out = new BufferedOutputStream(openFileOutput("archive.zip", Context.MODE_PRIVATE));

int fileSize = urlConnection.getContentLength();
if (fileSize == 0) {
return false;
}

int downloadedSize = 0;

byte[] data = new byte[1024];
int count = 0;

Calendar lastUpdate = Calendar.getInstance();

while ((count = in.read(data)) != -1) {
if (isCancelled()) {
Log.d(TAG, "Download cancelled.");

out.close();
in.close();
return false;
}

out.write(data, 0, count);
downloadedSize += count;

Calendar now = Calendar.getInstance();
if (now.getTimeInMillis() - lastUpdate.getTimeInMillis() >= 500) {
lastUpdate = now;
publishProgress(downloadedSize, fileSize);
}
}

out.close();
in.close();
}
catch (Exception ex) {
Log.e(TAG, "doInBackground()", ex);

return false;
}

return true;
}

最佳答案

首先,您可能通过减少调用 publishProgress(...) 来提高速度。在 doInBackground(...) 中设置一个守卫,这样它只会每 100、500、X 毫秒调用一次。

我无法确定一次将多少字节读入您的数据缓冲区。 IE。 in.read(data) 一次最多只能读取 1024 个字节吗?您可能想改用 BufferedInputStream

附带说明:如果任务成功完成,您不会调用 mWifiLock.release();

关于android - 在 AsyncTask 中的 Honeycomb 上下载大文件(> 100mb)会减慢 UI,可能是因为 GC?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7111235/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com