Ok+Rxjava+retrofit 기반 단점 전송 다운로드
1.Ok+Rxjava 기반 인 터 럽 트 다운로드
2.Ok+Rxjava+Retrofit 기반 인 터 럽 트 다운로드
이전 블 로그 에 서 는Ok+Rxjava 기반 인 터 럽 트 다운로드를 소개 했다.이 글 은 Ok+Rxjava+Retrofit 를 바탕 으로 정지점 전송 다운 로드 를 실현 하 는 것 을 소개 한다.데모 다운로드 주소효과 도 는 이전 사진 과 같다.하하
제 대체적인 생각 을 말씀 드 리 겠 습 니 다.(이전 편 과 약간 다 릅 니 다)파일 다운로드 url 에 따라 자신 이 정의 한 규칙 에 따라 파일 이름 을 만 들 고 로 컬 같은 경로 에서 이 파일 이 존재 하 는 지 판단 합 니 다.존재 한다 면 파일 크기 가 서버 에서 가 져 온 파일 크기 와 일치 하 는 경우 로 컬 파일 을 덮어 서 다시 다운로드 합 니 다.서버 에서 가 져 온 파일 보다 파일 크기 가 작 으 면 정지점 다운 로드 를 실행 하고 로 컬 파일 길이 부터 다운로드 합 니 다.파일 이 존재 하지 않 으 면 0 바이트 부터 다운로드 합 니 다.
또 다른 것 은 여기 서 파일 다운로드 의 진 도 를 감청 하고 사용자 정의 Downloadinterceptor 를 통 해 우리 의 새로운 DownloadResponse Body 를 설정 하여 우리 의 진도 감청 작업 을 완성 해 야 한 다 는 것 이다.
다음은 위의 주요 코드 입 니 다.
먼저 ResponseBody 를 다시 쓰 겠 습 니 다.
public class DownloadResponseBody extends ResponseBody {
private ResponseBody responseBody;
//
private DownFileCallback downFileCallback;
private BufferedSource bufferedSource;
private String downUrl;
public DownloadResponseBody(ResponseBody responseBody, DownFileCallback downFileCallback, String downUrl) {
this.responseBody = responseBody;
this.downFileCallback = downFileCallback;
this.downUrl = downUrl;
}
@Override
public MediaType contentType() {
return responseBody.contentType();
}
@Override
public long contentLength() {
return responseBody.contentLength();
}
@Override
public BufferedSource source() {
if (bufferedSource == null) {
bufferedSource = Okio.buffer(source(responseBody.source()));
}
return bufferedSource;
}
private Source source(Source source) {
return new ForwardingSource(source) {
long totalBytesRead = 0L;
File file = new File(DownloadManager.getInstance().getTemporaryName(downUrl));
@Override
public long read(Buffer sink, long byteCount) throws IOException {
long bytesRead = super.read(sink, byteCount);
totalBytesRead += bytesRead != -1 ? bytesRead : 0;
if (null != downFileCallback) {
if (bytesRead != -1) {
long loacalSize = file.length();//
long trueTotal = loacalSize + responseBody.contentLength() - totalBytesRead;//
downFileCallback.onProgress(trueTotal,loacalSize);
} else {
}
}
return bytesRead;
}
};
}
}
인 터 셉 터 다시 쓰기
public class Downloadinterceptor implements Interceptor {
private DownFileCallback downFileCallback;
private String downUrl;
public Downloadinterceptor(DownFileCallback listener,String downUrl) {
this.downFileCallback = listener;
this.downUrl = downUrl;
}
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
return response.newBuilder()
.body(new DownloadResponseBody(response.body(), downFileCallback,downUrl))
.build();
}
}
그리고 우리 서비스.
public interface HttpService {
/* Streaming , , oom*/
@Streaming
@GET
Observable<ResponseBody> download(@Header("range") String start, @Url String url);
}
다음은 저희 DownloadManager 에서 download 방법 입 니 다.
/**
*
* @param url
* @param downFileCallback
*/
public void download(final String url, final DownFileCallback downFileCallback) {
/* */
if (url == null || submap.get(url) != null) {
return;
}
Downloadinterceptor interceptor = new Downloadinterceptor(downFileCallback, url);
okHttpClient = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.build();
Retrofit retrofit = new Retrofit.Builder()
.client(okHttpClient)
.baseUrl("http://imtt.dd.qq.com")
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
final HttpService httpservice = retrofit.create(HttpService.class);
ProgressDownSubscriber subscriber =
Observable.just(url)
.flatMap(new Function<String, ObservableSource<DownloadInfo>>() {
@Override
public ObservableSource<DownloadInfo> apply(String s) throws Exception {
return Observable.just(createDownInfo(s));
}
})
.map(new Function<DownloadInfo, DownloadInfo>() {
@Override
public DownloadInfo apply(DownloadInfo s) throws Exception {
return getRealFileName(s);
}
})
.flatMap(new Function<DownloadInfo, Observable<ResponseBody>>() {
@Override
public Observable<ResponseBody> apply(DownloadInfo downInfo) throws Exception {
return httpservice.download("bytes=" + downInfo.getProgress() + "-", downInfo.getUrl());
}
})//
.map(new Function<ResponseBody, DownloadInfo>() {
@Override
public DownloadInfo apply(ResponseBody responsebody) {
try {
return writecache(responsebody, url);
} catch (IOException e) {
//* *//
e.printStackTrace();
}
return null;
}
})
.observeOn(AndroidSchedulers.mainThread())//
.subscribeOn(Schedulers.io())//
.subscribeWith(new ProgressDownSubscriber<DownloadInfo>() {
@Override
public void onNext(DownloadInfo downInfo) {
downFileCallback.onSuccess(downInfo);
submap.remove(downInfo.getUrl());
}
@Override
public void onError(Throwable t) {
downFileCallback.onFail(t.getMessage());
submap.remove(url);
}
});
submap.put(url, subscriber);
}
그리고 작업 일시 정지:
/**
*
*/
public void stop(String url) {
if (url == null) return;
if (submap.containsKey(url)) {
ProgressDownSubscriber subscriber = submap.get(url);
subscriber.dispose();
submap.remove(url);
}
}
서버 에서 파일 길이 가 져 오기
/**
*
*
* @param downloadUrl
* @return
*/
private long getContentLength(String downloadUrl) {
Request request = new Request.Builder()
.url(downloadUrl)
.build();
try {
Response response = mClient.newCall(request).execute();
if (response != null && response.isSuccessful()) {
long contentLength = response.body().contentLength();
response.close();
return contentLength == 0 ? DownloadInfo.TOTAL_ERROR : contentLength;
}
} catch (IOException e) {
e.printStackTrace();
}
return DownloadInfo.TOTAL_ERROR;
}
서버 에서 파일 길 이 를 가 져 올 때 주의 하 세 요.Android P 이후 api 28 이상 은 명문 네트워크 전송 을 금지 합 니 다.Android Manifest 의 application 태그 에"android:uses CleartextTraffic="true"를 표시 해 야 합 니 다.명문 전송 을 허용 합 니 다.사용 방법:우선 sd 카드 권한 획득
DownloadManager.getInstance().downloadPath( ).download(url1, new DownFileCallback() {
@Override
public void onSuccess(DownloadInfo info) {
Toast.makeText(MainActivity.this, url1 + " ", Toast.LENGTH_SHORT).show();
}
@Override
public void onFail(String msg) {
Toast.makeText(MainActivity.this, url1 + " ", Toast.LENGTH_SHORT).show();
}
@Override
public void onProgress(final long totalSize, final long downSize) {
// , 50M, 10M,
// onProgress totalSize
// 10M, 40M,downSize
// , , ,
runOnUiThread(new Runnable() {
@Override
public void run() {
int progress = (int) (downSize * 100 / totalSize);
progress1.setProgress(progress);
}
});
}
});
자,오늘 은 여기까지 입 니 다.여러분 에 게 도움 이 되 었 으 면 좋 겠 습 니 다.이것 은 저 에 게 도 깊 은 인상 을 주 는 노트 입 니 다.데모 다운로드 주소
github 주소:DownManager 환영 스타
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Ok+Rxjava 기반 인 터 럽 트 다운로드제 대체적인 생각 을 말씀 드 리 겠 습 니 다.파일 다운로드 url 에 따라 자신 이 정의 한 규칙 에 따라 파일 이름 을 만 들 고 로 컬 같은 경로 에서 이 파일 이 존재 하 는 지 판단 합 니 다.존재 한다 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.