我正在尝试编写一个在后台下载文件的应用程序。代码在尝试重新输入 doInBackground() 时崩溃。在返回之前将doing设置为false时会发生这种情况。代码如下 -
public class DownloadFile extends AsyncTask<String, Integer, String> {
private boolean doing;
private Activity activity;
private Intent intent;
private File beta;
private File alpha;
public DownloadFile(Activity act, Intent intent) {
this.activity = act;
this.intent = intent;
doing = false;
}
@Override
protected String doInBackground(String... sUrl) {
int fileCount = 0;
if (!download(sUrl[0] + "list.txt",
Environment.getExternalStorageDirectory() + "/alpha/list.txt")){
setDoing(false);
return "Download failed";//list.txt could not be downloaded. return error message.
}
fileCount++;
beta = new File(Environment.getExternalStorageDirectory() + "/beta/");
File betalist = new File(beta + "/list.txt");
alpha = new File(Environment.getExternalStorageDirectory() + "/alpha/");
File alphalist = new File(alpha + "/list.txt");
//verify that the file is changed.
if (alphalist.lastModified() == betalist.lastModified()// these two are
// never equal.
|| alphalist.length() == betalist.length()) { // better to check
// the length of
// the files.
setDoing(false);
return "Nothing to download.";
}
try {
FileReader inAlpha = new FileReader(alphalist);
BufferedReader br = new BufferedReader(inAlpha);
String s;
// read the name of each file in a loop
while ((s = br.readLine()) != null) {
// if(fileExistsInBeta(s)){
// copyFromBetaToAlpha(s);
// continue;
// }
// download the file.
//Url will truncate the trailing / so keep if statement as is.
if (!download(sUrl[0] + s,
Environment.getExternalStorageDirectory() + "/alpha/"
+ s)){
setDoing(false);
return "Failed at " + s;// the given file could not be downloaded. return error.
}
fileCount++;
}
br.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
Log.e("Pankaj", e.getMessage());
} catch (IOException e) {
// TODO Auto-generated catch block
Log.e("Pankaj", e.getMessage());
} catch (Exception e) {
Log.e("Pankaj", e.getMessage());
}
Log.d("Pankaj", "Download Done");
activity.overridePendingTransition(0, 0);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
activity.finish();
Log.d("Pankaj", "MainActivity Killed");
// rename alpha to beta
deleteSubFolders(beta.toString());
beta.delete();
alpha.renameTo(beta);
if (!alpha.exists()) {
alpha.mkdir();
}
File upper = new File(alpha + "/upper/");
if (!upper.exists())
upper.mkdirs();
File lower = new File(alpha + "/lower/");
if (!lower.exists())
lower.mkdirs();
// ConfLoader.getInstance().reload();//to refresh the settings
// restart the activity
activity.overridePendingTransition(0, 0);
activity.startActivity(intent);
Log.d("Pankaj", "MainActivity restarted");
// now reset done status so we can start again.
setDoing(false);
return "Download finished.";// return the status for onPostExecute.
}
private void copyFromBetaToAlpha(String fileName) {
File beta=new File(Environment.getExternalStorageDirectory()+"/beta/"+fileName);
File alpha=new File(Environment.getExternalStorageDirectory()+"/alpha/"+fileName);
try {
FileInputStream fis=new FileInputStream(beta);
FileOutputStream fos=new FileOutputStream(alpha);
byte[] buf=new byte[1024];
int len;
while((len=fis.read(buf))>0){
fos.write(buf, 0, len);
}
fis.close();
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
protected void onPostExecute(String result) {
Toast.makeText(activity, result, Toast.LENGTH_LONG).show();
super.onPostExecute(result);
}
public boolean download(String url, String file) {
boolean successful = true;
try {
URL u = new URL(url);
URLConnection conn = u.openConnection();
conn.connect();
int filelen = conn.getContentLength();
File f = new File(file);
// skip download if lengths are same
// because the file has been downed fully.
if (f.exists() && filelen == f.length()) {
return successful;
}
InputStream is = u.openStream();
DataInputStream dis = new DataInputStream(is);
byte[] buffer = new byte[1024];
int length;
FileOutputStream fos = new FileOutputStream(f);
while ((length = dis.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
fos.close();
buffer = null;
dis.close();
} catch (MalformedURLException mue) {
Log.e("SYNC getUpdate", "malformed url error", mue);
successful = false;
} catch (IOException ioe) {
Log.e("SYNC getUpdate", "io error", ioe);
successful = false;
} catch (SecurityException se) {
Log.e("SYNC getUpdate", "security error", se);
successful = false;
}
return successful;
}
private void deleteSubFolders(String uri) {
File currentFolder = new File(uri);
File files[] = currentFolder.listFiles();
if (files == null) {
return;
}
for (File f : files) {
if (f.isDirectory()) {
deleteSubFolders(f.toString());
}
// no else, or you'll never get rid of this folder!
f.delete();
}
}
public static int getFilesCount(File file) {
File[] files = file.listFiles();
int count = 0;
for (File f : files)
if (f.isDirectory())
count += getFilesCount(f);
else
count++;
return count;
}
public boolean isDoing() {
return doing;
}
/**
* @param doing
*/
public void setDoing(boolean doing) {
this.doing = doing;
}
private boolean fileExistsInBeta(final String fileName){
boolean exists=false;
File beta=new File(Environment.getExternalStorageDirectory()+"/beta/"+fileName);
if(beta.exists()){
String[] ext=beta.getName().split(".");
String extName=ext[ext.length-1];
exists=(extName!="txt" && extName!="tmr" && extName!="conf");
}
return exists;
}
在主要活动中 -
public void run() {
if (!downloadFile.isDoing()) {
downloadFile.execute(ConfLoader.getInstance().getListUrl());
downloadFile.setDoing(true);
}
// change the delay so that it covers the time for download and
// doesn't overlap causing multiple downloads jamming the bandwidth.
h.postDelayed(this, 1000);//check after 60 sec.
}
在 onCreate() -
downloadFile = new DownloadFile(this, getIntent());
h = new Handler();
h.postDelayed(this, 1000);
任何帮助表示赞赏。提前致谢。
编辑:logcat 错误是无法执行该任务已经在运行的任务。无法执行任务:任务已经执行(一个任务只能执行一次)。编辑:错误是否可能是因为我试图在 run() 中再次执行 asynchtask。也许 AsynchTask 不允许重新进入。