Android 强制关闭,使用asynctask下载文件
我有一个正在运行的下载功能。但是当我运行它的时候,80%的时候它会使我的手机滞后,强制关闭,很长一段时间没有响应,比如1~2分钟。这个案子是随机发生的,我真的找不到问题出在哪里。下载完成后,设备将恢复正常。我试过各种设备,比如galaxy S2、galaxy note、SE xperia Arc S和一些表格。问题依旧。有人能给我建议如何改进我的代码吗?以下是我现有的代码:Android 强制关闭,使用asynctask下载文件,android,android-asynctask,Android,Android Asynctask,我有一个正在运行的下载功能。但是当我运行它的时候,80%的时候它会使我的手机滞后,强制关闭,很长一段时间没有响应,比如1~2分钟。这个案子是随机发生的,我真的找不到问题出在哪里。下载完成后,设备将恢复正常。我试过各种设备,比如galaxy S2、galaxy note、SE xperia Arc S和一些表格。问题依旧。有人能给我建议如何改进我的代码吗?以下是我现有的代码: public void onClickDownload(View view){ String url =
public void onClickDownload(View view){
String url = "http://www.mydomain.com./" + fileURL;
url = url.replaceAll(" ","%20");
String sourceUrl = url;
new DownloadFileAsync().execute(sourceUrl);
}
public class DownloadFileAsync extends AsyncTask<String, Integer, Void> {
private boolean run_do_in_background = true;
@Override
protected void onPreExecute(){
super.onPreExecute();
}
@Override
protected Void doInBackground(String... aurl) {
int count;
try {
URL url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
int lengthOfFile = conexion.getContentLength();
Log.d("ANDRO_ASYNC", "Lenght of file: " + lengthOfFile);
File folder = new File(Environment.getExternalStorageDirectory() + "/MaxApps");
boolean success = false;
if (!folder.exists()) {
success = folder.mkdirs();
}
if (!success) {
} else {
}
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream("/sdcard/MaxApps/" + apkURL);
byte data[] = new byte[100*1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
int progressPercent = (int) ((total*100)/lengthOfFile);
if(progressPercent % 5 == 0){
publishProgress(progressPercent);
}
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {
notificationManager.cancel(Integer.parseInt(ID.toString()));
Notification MyN = new Notification(); MyN.icon = R.drawable.logo1;
MyN.tickerText = "Download Failed";
MyN.number = 1;
MyN.setLatestEventInfo (getApplicationContext(), apkURL + " Download Failed.", "Please try again", MyPI);
MyN.flags |= Notification.FLAG_AUTO_CANCEL;
MyNM.notify(1, MyN);
run_do_in_background = false;
}
return null;
}
@Override
protected void onProgressUpdate(Integer... progress) {
notification.contentView.setProgressBar(R.id.pbStatus, 100, progress[0], false);
notificationManager.notify(Integer.parseInt(ID.toString()), notification);
}
@Override
protected void onPostExecute(Void unused) {
if(run_do_in_background) {
notificationManager.cancel(Integer.parseInt(ID.toString()));
Notification MyN = new Notification(); MyN.icon = R.drawable.logo1;
MyN.tickerText = "Download Complete";
MyN.number = 1;
MyN.setLatestEventInfo (getApplicationContext(), "Download Complete, Click to install.", apkURL, MyPI);
MyN.flags |= Notification.FLAG_AUTO_CANCEL;
MyNM.notify(Integer.parseInt(ID.toString()) , MyN);
}
}
}
更新UI可能需要很长时间?也许你可以试着这样测试,看看它是否有区别:
@Override
protected void onProgressUpdate(Integer... progress) {
Log.d("ANDRO_ASYNC", "Progress: " + progress[0]);
}
顺便说一下,这与您的要求无关,但我认为您在处理进度的代码中存在问题:
int progressPercent = (int) ((total*100)/lengthOfFile);
if(progressPercent % 5 == 0){
publishProgress(progressPercent);
}
只有当进度精确到5、10、15、20%等时,才会更新进度。。。我猜您实际上希望在进度至少比以前多%5的情况下更新进度
int previousProgress = 0;
while ((count = input.read(data)) != -1) {
total += count;
int progressPercent = (int) ((total*100)/lengthOfFile);
if(progressPercent - previousProgress >= 5) {
previousProgress = progressPercent;
publishProgress(progressPercent);
}
output.write(data, 0, count);
}
我不太喜欢您在onProgressUpdate中更新通知,因为您在UI线程中执行这些操作,然后以某种方式阻止它。如何创建和执行DownloadFileAsync对象?是的,我确实为我的notificationbar创建了一个新的UI以满足我的需要,那么我应该怎么做?这是问题的原因吗@Caner,检查更新:您正在下载的文件有多大?@Caner,从50kb到50mb。。50kb无法真正看到效果,因为它可以在一瞬间完成。感谢您的回复,但我有一些问题:带>=5的%5之间的实际区别是什么?他们只是做同样的事,对吗?u提供的新计算看起来像是让系统做更多的工作?假设进度是恒定的,每次是%6。所以它将是这样的:6,12,18,24,30,。。。您的代码将仅在UI为%30、60%、90%时更新UI。我的建议将每次更新,是的,这是更多的工作。但我只是觉得你的代码没有达到你的目的。那项建议与你的问题无关。。