다중 스레드 다운로드를 위한 RxJava 및 retrofit
장면은 매우 간단하다. 서버는 3개의 파일 다운로드 주소를 제공한다.클라이언트가 단추를 눌러서 이 파일들을 비동기적으로 다운로드합니다.이것은 다중 스레드 다운로드와 관련이 있다.
Retrofit 섹션:
BaseApi:
/**
* songwenju on 16-8-5 : 16 : 09.
* :[email protected]
*/
public class BaseApi {
//
public static OkHttpClient mOkHttpClient = new OkHttpClient.Builder()
.readTimeout(AppConstant.READ_TIMEOUT, TimeUnit.SECONDS)//
.writeTimeout(AppConstant.WRITE_TIMEOUT,TimeUnit.SECONDS)//
.connectTimeout(AppConstant.CONNECT_TIMEOUT,TimeUnit.SECONDS)//
.build();
}
DownloadApi: 여기는 하나의 단례입니다. 게으름뱅이와 굶주린 식의 특성을 결합한 것입니다. 이것은 라인이 안전하고 실례가 하나입니다./**
* songwenju on 16-8-23 : 16 : 32.
* :[email protected]
*/
public class DownloadApi extends BaseApi{
// DownloadApi
private static DownloadApi mDownloadApi = new DownloadApi();
private DownloadService mDownloadService;
public static DownloadApi getInstance(){
return mDownloadApi;
}
private DownloadApi(){
Retrofit retrofit = new Retrofit.Builder()
.client(mOkHttpClient)
.baseUrl(AppConstant.BASE_URL)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
mDownloadService = retrofit.create(DownloadService.class);
}
public DownloadService getDownloadService() {
return mDownloadService;
}
}
Download Service: Streaming 메모를 사용합니다. 이 메모는 큰 파일을 다운로드하는 데 사용됩니다.메모가 추가되면 다운로드 파일은 모든 다운로드 내용을 메모리에 불러오지 않습니다.
/**
* songwenju on 16-8-23 : 16 : 32.
* :[email protected]
*/
public interface DownloadService {
@Streaming
@GET
Observable downloadFile(@Url String fileUrl);
}
WriteFile Manager: ResponseBody를 받은 내용을 파일에 기록합니다./**
*
*/
public class WriteFileManager {
private static final String TAG = "DownLoadManager";
public static boolean writeResponseBodyToDisk(ResponseBody body,String downloadName) {
String path = FileUtil.getVideoPath() + downloadName;
LogUtil.i(TAG, "WriteFileManager.startToWrite.path:" + path);
File futureFile = new File(path);
InputStream inputStream = null;
OutputStream outputStream = null;
long fileSize = body.contentLength();
LogUtil.d(TAG,"WriteFileManager.writeResponseBodyToDisk.fileSize:"+fileSize);
try {
try {
byte[] fileReader = new byte[1024 * 1024];
long fileSizeDownloaded = 0;
inputStream = body.byteStream();
outputStream = new FileOutputStream(futureFile);
while (true) {
int read = inputStream.read(fileReader);
if (read == -1) {
break;
}
outputStream.write(fileReader, 0, read);
fileSizeDownloaded += read;
// LogUtil.i(TAG, "file download: " + fileSizeDownloaded + " of " + fileSize);
}
LogUtil.d(TAG, "file download: " + fileSizeDownloaded + " of " + fileSize);
outputStream.flush();
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
} catch (IOException e) {
return false;
}
}
}
activity에서:merge를 사용하여observable를 통합합니다.
public class MainActivity extends AppCompatActivity {
private DownloadService mDownloadService;
private List mDownloadList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DownloadApi downloadApi = DownloadApi.getInstance();
mDownloadService = downloadApi.getDownloadService();
final String downloadUrl1 = AppConstant.DOWNLOAD_URL1;
final String downloadUrl2 = AppConstant.DOWNLOAD_URL2;
final String downloadUrl3 = AppConstant.DOWNLOAD_URL3;
mDownloadList = new ArrayList<>();
mDownloadList.add(downloadUrl1);
mDownloadList.add(downloadUrl2);
mDownloadList.add(downloadUrl3);
}
/**
*
* @param view view
*/
public void download(View view) {
LogUtil.i(this, "MainActivity.download.");
List> observables = new ArrayList>();
// Observable List
for (int i = 0; i < mDownloadList.size(); i++) {
final String downloadUrl = mDownloadList.get(i);
observables.add(mDownloadService.downloadFile(downloadUrl)
.subscribeOn(Schedulers.io())
.map(new Func1() {
@Override
public Boolean call(ResponseBody responseBody) {
return WriteFileManager.writeResponseBodyToDisk(responseBody, downloadUrl);
}
}).subscribeOn(Schedulers.io()));
}
//Observable merge Observable Observable, observable 。
Observable.merge(observables).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
}
@Override
public void onNext(Boolean b) {
if (b) {
Toast.makeText(MainActivity.this, "Download is sucess", Toast.LENGTH_LONG).show();
}
}
});
}
}
log:01-09 05:24:04.474 28625-28625/? I/swj_htv_MainActivity: MainActivity.download.
01-09 05:24:04.574 28625-28786/? I/swj_htv_DownLoadManager: DownloadManager.startToWrite.path:/storage/emulated/0/Movies/mvp.wmv
01-09 05:24:04.575 28625-28786/? D/swj_htv_DownLoadManager: DownloadManager.writeResponseBodyToDisk.fileSize:400937223
01-09 05:24:04.575 28625-28785/? I/swj_htv_DownLoadManager: DownloadManager.startToWrite.path:/storage/emulated/0/Movies/chess.mp4
01-09 05:24:04.575 28625-28785/? D/swj_htv_DownLoadManager: DownloadManager.writeResponseBodyToDisk.fileSize:6366633
01-09 05:24:04.575 28625-28784/? I/swj_htv_DownLoadManager: DownloadManager.startToWrite.path:/storage/emulated/0/Movies/protein.mp4
01-09 05:24:04.575 28625-28784/? D/swj_htv_DownLoadManager: DownloadManager.writeResponseBodyToDisk.fileSize:374081533
01-09 05:24:06.039 28625-28785/? D/swj_htv_DownLoadManager: file download: 6366633 of 6366633
01-09 05:25:12.286 28625-28784/? D/swj_htv_DownLoadManager: file download: 374081533 of 374081533
01-09 05:25:14.302 28625-28786/? D/swj_htv_DownLoadManager: file download: 400937223 of 400937223
프로젝트에 대응하는 데모가 github에 업로드되었습니다.
RxJavaRetrofitDownload
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.