06-09 19:14:28.193 23503-23503/com.wodi.who W/System.err: java.net.SocketTimeoutException: timeout
06-09 19:14:28.193 23503-23503/com.wodi.who W/System.err: at okhttp3.internal.http2.Http2Stream$StreamTimeout.newTimeoutException(Http2Stream.java:593)
06-09 19:14:28.193 23503-23503/com.wodi.who W/System.err: at okhttp3.internal.http2.Http2Stream$StreamTimeout.exitAndThrowIfTimedOut(Http2Stream.java:601)
06-09 19:14:28.193 23503-23503/com.wodi.who W/System.err: at okhttp3.internal.http2.Http2Stream$FramingSource.waitUntilReadable(Http2Stream.java:374)
06-09 19:14:28.193 23503-23503/com.wodi.who W/System.err: at okhttp3.internal.http2.Http2Stream$FramingSource.read(Http2Stream.java:337)
06-09 19:14:28.193 23503-23503/com.wodi.who W/System.err: at okio.ForwardingSource.read(ForwardingSource.java:35)
06-09 19:14:28.194 23503-23503/com.wodi.who W/System.err: at okio.RealBufferedSource$1.read(RealBufferedSource.java:409)
06-09 19:14:28.194 23503-23503/com.wodi.who W/System.err: at java.io.InputStream.read(InputStream.java:162)
06-09 19:14:28.194 23503-23503/com.wodi.who W/System.err: at com.liulishuo.filedownloader.download.FetchDataTask.run(FetchDataTask.java:106)
06-09 19:14:28.194 23503-23503/com.wodi.who W/System.err: at com.liulishuo.filedownloader.download.DownloadRunnable.run(DownloadRunnable.java:101)
06-09 19:14:28.194 23503-23503/com.wodi.who W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
06-09 19:14:28.194 23503-23503/com.wodi.who W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
06-09 19:14:28.194 23503-23503/com.wodi.who W/System.err: at java.lang.Thread.run(Thread.java:818)
当使用https://github.com/Jacksgong/filedownloader-okhttp3-connection来支持Http 302问题时,OPPO R9s上报了上述问题,操作是,执行了第一次下载,第二次下载就会报错,使用的filedownloader库是1.5.3
感谢反馈。不过....
FetchDataTask 106行 InputStream.read),这个应该是1.5.2版本。SocketTimeoutException 并非是302等问题,而是在弱网/远端服务器网络链路出现故障时无论任何链接都有可能遇到的socket 连接/读取超时报的错误。FileDownloadListener#error中(代码中有catch了其父类型IOException的所有错误,也会覆盖这个catch),这是一个正确的反馈,因此这个不是bug,而是希望遇到该网络问题时,上层做对应的处理。可是我下载成功一次后,再下载别的就一直报这个错,真的很奇怪,我不用Okhttp就可以一直下载@Jacksgong
好的,你做下以下验证:
filedownloader-okhttp3-connection,同时引用最新版本okhttp3即可(关于引用冲突可以这篇文章中的引用关系)别的连接是存在问题的,换成别的连接,或者和第一个连接调换试试。SocketTimeoutException,然后杀掉进程,又是第一次成功,后面又失败呢?我刚刚在demo中验证:
cn.dreamtobe.filedownloader:filedownloader-okhttp3-connection:1.0.0DemoApplication中注册: FileDownloader.init(this, new DownloadMgrInitialParams.InitCustomMaker().connectionCreator(new OkHttp3Connection.Creator()));你看看我上面的步骤是否与你的复现步骤相符合。
该问题,应该是你的 别的连接 那个连接存在问题。我这边按照你的复现步骤无法复现该问题。建议你也在demo中进行尝试,替换连接进行尝试。 有进一步跟进该Issue将被重新打开。
我的情况和 该问题是和进程有关吗,是否是下载成功一次,之后无论下载什么连接都是失败而且都是SocketTimeoutException,然后杀掉进程,又是第一次成功,后面又失败呢? 很吻合
public int downloadCocosUpdate(final Context context, final String downloadUrl, final String gamePath, final String passWord, final Map
downloadId = 0;
FragmentTransaction ft = ((BaseActivity) context).getSupportFragmentManager().beginTransaction();
Fragment prev = ((BaseActivity) context).getSupportFragmentManager().findFragmentByTag(DOWNLOAD_DIALOG_TAG);
if (prev != null) {
ft.remove(prev);
}
final DownloadDialogFragment newFragment = DownloadDialogFragment.newInstance();
newFragment.show(ft, DOWNLOAD_DIALOG_TAG);
final String newGamePath = gamePath.contains("wolf") ? "wolf" : gamePath;
// 首先删除文件夹下面的文件
Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
// 首先删除文件
File file = new File(BaseConfig.COCOS_FILE_DIR +
(TextUtils.isEmpty(newGamePath) ? "" : File.separator + newGamePath));
FileUtil.deleteDirRecursive(file);
subscriber.onCompleted();
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
// 执行下载过程
downloadId = FileDownloader.getImpl().create(downloadUrl)
.setPath(BaseConfig.COCOS_FILE_DIR + (TextUtils.isEmpty(newGamePath) ? "" : File.separator + newGamePath)
+ File.separator + COCOS_GAME_UPDATE)
.setListener(new FileDownloadListener() {
@Override
protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
}
@Override
protected void connected(BaseDownloadTask task, String etag, boolean isContinue, int soFarBytes, int totalBytes) {
}
@Override
protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
final int dl_progress = (int) (soFarBytes * 100L) / totalBytes;
Timber.d("progress: " + dl_progress);
((Activity) context).runOnUiThread(new Runnable() {
@Override
public void run() {
if (newFragment.getDownloadProgressBar() != null) {
newFragment.getDownloadProgressBar().setProgress(dl_progress);
}
}
});
}
@Override
protected void blockComplete(BaseDownloadTask task) {
}
@Override
protected void retry(final BaseDownloadTask task, final Throwable ex, final int retryingTimes, final int soFarBytes) {
}
@Override
protected void completed(BaseDownloadTask task) {
((Activity) context).runOnUiThread(new Runnable() {
@Override
public void run() {
if (newFragment.getDownloadProgressBar() != null) {
newFragment.getDownloadProgressBar().setProgress(100);
}
}
});
// 同时, 对下载成功的文件进行解压
Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
try {
unZipCocos(BaseConfig.COCOS_FILE_DIR +
(TextUtils.isEmpty(newGamePath) ? "" : File.separator + newGamePath), passWord + "_xiangbudao", params);
} catch (ZipException e) {
e.printStackTrace();
} finally {
DialogFragment prev = (DialogFragment) ((BaseActivity) context).getSupportFragmentManager().findFragmentByTag(DOWNLOAD_DIALOG_TAG);
if (prev != null) {
prev.dismissAllowingStateLoss();
}
}
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe();
}
@Override
protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
}
@Override
protected void error(BaseDownloadTask task, Throwable e) {
e.printStackTrace();
((Activity) context).runOnUiThread(new Runnable() {
@Override
public void run() {
DialogFragment prev = (DialogFragment) ((BaseActivity) context).getSupportFragmentManager().findFragmentByTag(DOWNLOAD_DIALOG_TAG);
if (prev != null) {
prev.dismissAllowingStateLoss();
}
Toast.makeText(context, context.getResources().
getString(R.string.str_please_retry), Toast.LENGTH_SHORT).show();
}
});
}
@Override
protected void warn(BaseDownloadTask task) {
}
}).start();
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
}
});
return downloadId;
}
代码是这样写的,然后Activity中调用
你在demo project中可以复现该问题吗,根据我的步骤: https://github.com/lingochamp/FileDownloader/issues/606#issuecomment-307375256 ,我刚刚按照这个步骤无法复现你的问题。
@或者简单点,我刚刚已经push上去了,你可以拉下来case/okhttp3分支,这个分支就是1.5.3,并且适配了okhttp3,
SingleTaskTestActivity中替换createDownloadTask中的连接为你的连接进行测试看看。有时下载下来的文件是.temp文件,而且貌似一出现这种情况,就会稳定复现,下不下来文件
cn.dreamtobe.filedownloader:filedownloader-okhttp3-connection:1.0.0
不加这个就不存在这个问题
@Jacksgong 这个可以给点改正的建议吗?
我明天给你看下,今晚有其他重要的事情要处理。
@wanghaihui
.temp文件是下载过程中的临时文件,文件只要没有完成下载都是.temp这是正常的情况。warn是当前已经有该任务在下载,又启动相同任务,新启动的任务就会接收到warn的回调,原下载不会受到影响。FileDownloader并没有对你的连接做特殊处理,而okhttp3支持处理了连接层的事务。
找到问题根源了:
经常回调started后,就要等待很久很久,然后就回调error超时了。这个过程将没有任何响应,原因是一直在建连。
在started后,在与资源后台建连:
warn这个符合预期的,因为FileDownloader中已经有一个完全相同的任务正在执行;.temp这个是符合预期的,该文件是用于断点续传,下一次启动下载的时候会继续将数据写入该文件,直到下载完成后,会将该文件重命名为目标文件;好的,多谢~
Most helpful comment
找到问题根源了:
该问题不是BUG,而是该资源网络连接十分不稳定。
经常回调
started后,就要等待很久很久,然后就回调error超时了。这个过程将没有任何响应,原因是一直在建连。在
started后,在与资源后台建连:warn这个符合预期的,因为FileDownloader中已经有一个完全相同的任务正在执行;.temp这个是符合预期的,该文件是用于断点续传,下一次启动下载的时候会继续将数据写入该文件,直到下载完成后,会将该文件重命名为目标文件;