Have a pretty simple code for download file.
class Downloader {
private static Downloader Dinstance = null;
private boolean isAborted = false;
void setAborted(boolean isAborted) {
isAborted = true;
}
int getAborted() {
return isAborted;
}
static Downloader getInstance(@NonNull Context context) {
if (Dinstance == null)
Dinstance = new Downloaderr(context.getApplicationContext());
return Dinstance;
}
private Downloader() {
...
}
function download() {
...
try {
URL url = new URL(RequestedURL);
InputStream inputStream = url.openStream();
DataInputStream dataInputStream = new DataInputStream(inputStream);
FileOutputStream fileOutputStream = new FileOutputStream(FileName);
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = dataInputStream.read(buffer)) > 0) {
fileOutputStream.write(buffer, 0, bytesRead);
if (getAborted()) {
Log.d(static_variables.TAG, "Aborting 1");
fileOutputStream.close();
Log.d(static_variables.TAG, "Aborting 2");
dataInputStream.close();
Log.d(static_variables.TAG, "Aborting 3");
inputStream.close();
Log.d(static_variables.TAG, "All closed");
file.delete();
downloadFinished = true;
Log.d(static_variables.TAG, "Returning");
return false;
}
fileOutputStream.close();
dataInputStream.close();
inputStream.close();
} catch (IOException e) {
downloadFinished = true;
return false;
}
...
}
}
In MainActivity
First button listener(start download):
function onClick() {
new Thread(new Runnable() {
@Override
public void run() {
Downloader.getInstance().download(...);
}
}).start();
}
Second button listener:
function onClick() {
Downloader.getInstance().setAborted(true);
}
Download going in thread.
In logs time for dataInputStream.close();
is biggest. And other research shows that streams won't close before file will be fully downloaded.
How I can terminate InputStream
in progress?
During research I found two things.
Download aborts with this approach, but there is a buffer and for small files(songs, in my case) it's almost untrackable. For 500Mb file download, when you press abort on 15Mb downloaded, then after 16-17 it will stop.
If you want(as I am) terminate download faster, then you should use another approach. When starting Thread, save pointer int variable.
Thread threadDownload = new Thread(...);
threadDownload.start();
then abort using
threadDownload.interrupt();
Beware. You'll need remove temporary file by yourself. File which you use in OutputStream
.
You also will have some buffer overhead, but it will be not 1-2Mb, but 200-300Kb.