[英]isCancelled() not Working in android Async Task
I want to cancel a downloading file using async task, i tried below code, here isCancelled() method is not working, can any one suggest how can i stop download. 我想使用异步任务取消下载文件,我尝试了下面的代码,这里isCancelled()方法不起作用,有人可以建议我如何停止下载。
vid1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
down d1=new down();
if(vid1.getText().toString().equals("Start")){
Log.v("Vid 1", "Vid 1");
vid1.setText("Pause");
d1.execute(url1,"one");
}else if(vid1.getText().toString().equals("Pause")){
vid1.setText("Start");
Log.v("Vid 1 Else", "Vid 1 Else");
if(d1!=null && d1.getStatus()!=AsyncTask.Status.FINISHED){
d1.cancel(true);
}
}
}
});
vid2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Log.v("Vid 2", "Vid 2");
// TODO Auto-generated method stub
down d2=new down();
if(vid2.getText().toString().equals("Start")){
vid2.setText("Pause");
d2.execute(url2,"two");
}else if(vid2.getText().toString().equals("Pause")){
vid2.setText("Start");
Log.v("Vid 2 Else", "Vid 2 Else ");
d2.cancel(true);
}
}
});
}
private class down extends AsyncTask<String, Void, String>{
RandomAccessFile output ;
boolean cancel=false;
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
Log.v("Pre Execute", "Pre Execute");
}
@Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
File outputFileCache=new File(Environment.getExternalStorageDirectory()+"/pau/"+params[1]+".mp4");
try {
Long download_ok = null ;
int fileLength;
URL url = new URL(params[0]);
HttpURLConnection connection = (HttpURLConnection) url.openConnection() ;
if (outputFileCache.exists())
{
Log.v(">>>>>>", "Exists");
connection.setAllowUserInteraction(true);
connection.setRequestProperty("Range", "bytes=" + outputFileCache.length() + "-");
}
connection.setConnectTimeout(14000);
connection.setReadTimeout(20000);
connection.connect();
if (connection.getResponseCode() / 100 != 2)
throw new Exception("Invalid response code!");
else
{
String connectionField = connection.getHeaderField("content-range");
if (connectionField != null)
{
String[] connectionRanges = connectionField.substring("bytes=".length()).split("-");
download_ok = Long.valueOf(connectionRanges[0]);
Log.v("download ok", ""+download_ok);
}
if (connectionField == null && outputFileCache.exists())
outputFileCache.delete();
if(download_ok==null){
download_ok=(long) 0;
}
fileLength = (int) (connection.getContentLength() + download_ok);
Log.v("file length", ""+fileLength);
input = new BufferedInputStream(connection.getInputStream());
output = new RandomAccessFile(outputFileCache, "rw");
output.seek(download_ok);
byte data[] = new byte[1024];
int count = 0;
int __progress = 0;
while ((count = input.read(data, 0, 1024)) != -1 && __progress!=100)
{
Log.v(">>>>>>>>>>>progress cancelled", "<<<<<<<<<"+isCancelled());
if(isCancelled()){
Log.v(">>>>>>>>>>>>>>>>>>>>>>>>>>>", "<<<<<<<<<"+isCancelled());
break;
}else{
download_ok += count;
output.write(data, 0, count);
__progress = (int) ((download_ok * 100) / fileLength);
}
}
output.close();
input.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
Found your problem: You are creating a new instance of the Asynctask with every click, eg 发现问题所在:您每次点击都在创建Asynctask的新实例,例如
down d2=new down();
This means that you are calling cancel on a different AsyncTask object. 这意味着您要在另一个AsyncTask对象上调用cancel。 You need to move this line into your check for the start click and also use a field and not a local variable ie
您需要将此行移至开始点击检查中,并使用一个字段而不是局部变量,即
if(vid2.getText().toString().equals("Start")) {
d2 = new down();
vid2.setText("Pause");
d2.execute(url2,"two");
}
where d2 is set in your class. 在您的班级中设置d2的位置。 Also note that class names should always start with capital letters, ie
class Down
instead of class down
. 另请注意,类名应始终以大写字母开头,即
class Down
而不是class down
。
You can store the Asynctask in a global class array that is equal in length to the number of videos. 您可以将Asynctask存储在长度与视频数量相等的全局类数组中。
Down downTasks[] = new Down[TOTAL VIDEOS];
Then you initialise the Views, similar to what you already did, here shown for one View
然后您初始化视图,类似于您已经做过的,此处显示的是一个
View
vid1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(vid1.getText().toString().equals("Start")){
Log.v("Vid 1", "Vid 1");
vid1.setText("Pause");
downTasks[0] = new down();
downTasks[0].execute(url1,"one");
}
else if(vid1.getText().toString().equals("Pause")){
vid1.setText("Start");
Log.v("Vid 1 Else", "Vid 1 Else");
if(downTasks[0]!=null && downTasks[0].getStatus()!=AsyncTask.Status.FINISHED){
downTasks[0].cancel(true);
}
}
}
});
Note that this code is quite redundant because you rewrite almost exactly the same code for every View
, this can be nicely refactored with a for
loop, but I leave that as an exercise for you if you feel like it. 请注意,此代码是非常多余的,因为您为每个
View
重写几乎完全相同的代码,可以使用for
循环很好地对其进行重构,但是如果您愿意,我可以将其作为练习留给您。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.