Open hassan379 opened 9 years ago
I have the same problem when I pause a resumable task: dm.pause(token); it called the sequence : onpause → rebuild → rebuild finish → complete so I can`t resume the download any more
this happened only with android lolipop 5.0.1 in earlier versions it works perfectly..
Did you check that on handheld device or on an emulator?
@majidgolshadi thanks for the fast response, I am working on real device.
i tested it on real device and emulator and both the same result , please fix this issue your library is very great and i only faced this issue on it
after days of hardworking i have found the source of the error , in Asyncworker
:
if (!this.isInterrupted()) {
observer.rebuild(chunk);
Log.i("isInterrupted()","yes");
}
for some reason this if statement become true after we call pausedownload
, and for this reason observer call rebuild to finish the download , i saw this issue only on 5.0 , i compared this on other apis , the if statement was false when we call pausedownload
sorry bad english
UPDATE:
i notice something that .isInterrupted() return false even after we interrupt every chunk thread , but in other apis return true
FIXED : I fixed this issue by adding flag inside AsyncWorker , i name it as "isInturrputed" , the default value of this flag is false and became true when trying to inturrput every thread chunk , the code now became like this AsyncWorker Class :
package tools.majid.core.chunkWorker;
import android.os.Build;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import tools.majid.Utils.helper.FileUtils;
import tools.majid.database.elements.Chunk;
import tools.majid.database.elements.Task;
/**
* Created by Majid Golshadi on 4/14/2014.
*/
public class AsyncWorker extends Thread{
private final int BUFFER_SIZE = 1024;
private final Task task;
private final Chunk chunk;
private final Moderator observer;
private byte[] buffer;
private ConnectionWatchDog watchDog;
private Boolean isInterrupted=false;
public boolean stop = false;
public AsyncWorker(Task task, Chunk chunk, Moderator moderator){
buffer = new byte[BUFFER_SIZE];
this.task = task;
this.chunk = chunk;
this.observer = moderator;
}
public void setInterrupt()
{
isInterrupted=true;
}
@Override
public void run() {
try {
URL url = new URL(task.url);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(50000);
connection.setReadTimeout(50000);
if (chunk.end != 0) // support unresumable links
connection.setRequestProperty("Range", "bytes=" + chunk.begin + "-" + chunk.end);
connection.connect();
File cf = new File(FileUtils.address(task.save_address, String.valueOf(chunk.id)));
InputStream remoteFileIn = connection.getInputStream();
FileOutputStream chunkFile = new FileOutputStream(cf, true);
int len = 0;
// set watchDoger to stop thread after 1sec if no connection lost
watchDog = new ConnectionWatchDog(5000, this);
watchDog.start();
while (!this.isInterrupted() &&
(len = remoteFileIn.read(buffer)) > 0) {
watchDog.reset();
chunkFile.write(buffer, 0, len);
process(len);
}
chunkFile.flush();
chunkFile.close();
watchDog.interrupt();
connection.disconnect();
if(Build.VERSION.SDK_INT==21)
{
if(!isInterrupted)
{
observer.rebuild(chunk);
Log.i("isInterrupted()","yes");
}
}
else
{
if (!this.isInterrupted()) {
observer.rebuild(chunk);
Log.i("isInterrupted()","yes");
}
}
}catch (SocketTimeoutException e) {
e.printStackTrace();
observer.connectionLost(task.id);
puaseRelatedTask();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return;
}
private void process(int read) {
observer.process(chunk.task_id, read);
}
private void puaseRelatedTask() {
observer.pause(task.id);
}
private boolean flag = true;
public void connectionTimeOut(){
if (flag) {
watchDog.interrupt();
flag = false;
observer.connectionLost(task.id);
puaseRelatedTask();
}
}
}
and the block of code that handle inturrputing every thread chunk in Moderator Class became like this :
List<Chunk> taskChunks =
chunksDataSource.chunksRelatedTask(task.id);
for (Chunk chunk : taskChunks) {
Thread worker = workerList.get(chunk.id);
if (worker != null) {
worker.interrupt();
if(Build.VERSION.SDK_INT==21)
((AsyncWorker)worker).setInterrupt();
workerList.remove(chunk.id);
Log.i("workerListremove",String.valueOf(chunk.id));
}
}
thx to me for fixing this issue :P
Send your bug fix with pull request (pr)
I had a similar bug reported from crashlytics. But I couldn't reproduce this. How can I encounter this with some steps?
hi , thx for this great library but i am facing issue , in lolipop 5.0 ondownloadFinished Called Directly after connectionlost , but on other apis it works fine even on 5.1 , this issue appear only in 5.0 i noticed that an error raised 07-31 16:50:06.941 1670-1804/com.filmov.itech.movies E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-229 Process: com.filmov.itech.movies, PID: 1670 java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.FileInputStream.read(byte[])' on a null object reference at tools.majid.core.chunkWorker.Rebuilder.run(Rebuilder.java:52)