Reputation: 15821
I have class that represents a download task unit.
import android.os.Environment;
import android.util.Log;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
/**
* Created by Sergey Shustikov ([email protected]) at 2015.
*/
public class DownloadTask extends Thread implements DownloadActions
{
private DownloadStateListener mListener;
private String mDownloadLink;
public DownloadTask(String downloadLink)
{
mDownloadLink = downloadLink;
}
@Override
public void cancel()
{
interrupt();
mListener.onDownloadCanceled(mDownloadLink);
}
@Override
public void setDownloadStateChangedListener(DownloadStateListener listener)
{
mListener = listener;
}
@Override
public void run()
{
int count;
try {
mListener.onDownloadStarted(mDownloadLink);
URL url = new URL(mDownloadLink);
URLConnection connection = url.openConnection();
connection.connect();
// this will be useful so that you can show a tipical 0-100%
// progress bar
int contentLength = connection.getContentLength();
// download the file
InputStream input = new BufferedInputStream(connection.getInputStream());
// Output stream
OutputStream output = new FileOutputStream(Environment.getExternalStorageDirectory().toString() + "/Download/");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
mListener.onDownloadProgress(mDownloadLink, (int) ((total * 100) / contentLength));
// writing data to file
output.write(data, 0, count);
}
close(connection, input, output);
mListener.onDownloadFinished(mDownloadLink);
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
mListener.onDownloadFailed(mDownloadLink, new DownloadError(e.getMessage()));
}
}
private synchronized void close(URLConnection connection, InputStream input, OutputStream output)
{
try {
// flushing output
if (output != null) {
output.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
// closing streams
try {
// flushing output
if (output != null) {
output.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
// flushing output
if (input != null) {
input.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
I need to stop downloading, clear downloaded data and close connection when i call cancel()
method.
I know - there are many discussion about stop mechanism in Java.
I can't use this answer :
You can create a boolean field and check it inside run:
public class Task implements Runnable { private volatile boolean isRunning = true; public void run() { while (isRunning) { //do work } } public void kill() { isRunning = false; } }
To stop it just call
task.kill();
This should work.
because it is no operation in loop.
So how i can correctly do that?
Upvotes: 0
Views: 399
Reputation: 8580
You cant interrupt a thread unless the code you let the thread run is interruptable - that is - checking for itself if it was interrupted.
EDIT In your case - something like :
final Thread cancelable = new Thread() {
@Override
public void run() {
int count;
try {
...
while ((count = input.read(data)) != -1 && !Thread.interrupted()) {
total += count;
// publishing the progress....
// After this onProgressUpdate will be called
mListener.onDownloadProgress(mDownloadLink, (int) ((total * 100) / contentLength));
// writing data to file
output.write(data, 0, count);
}
if ( Thread.interrupted() ) {
mListener.onDownloadCanceled(mDownloadLink);
}
...
}
}
}
});
and to stop the download you must call :
cancelable.interrupt();
Upvotes: 1
Reputation: 1518
public class Task implements Runnable {
private boolean cancel;
public void run() {
try{
while (yourCondition) {
//do work
if(cancel){
throw new DownloadCancelException();
}
}
}catch(DownloadCancelException e){
//clear downloaded stuff over here
}
}
public void kill() {
cancel = true;
}
}
Upvotes: 0
Reputation: 18123
You have to interrupt your (potentially long-running) reading process:
while ((count = input.read(data)) != -1 && isRunning) {
// perform reading
}
Upvotes: 2