MVP Retrofit多线程下载
来源:互联网 发布:淘宝网休闲裤子 编辑:程序博客网 时间:2024/05/18 03:45
多线程下载:
目的:最大限度的利用CPU资源
过程:
1.获得下载文件的长度,然后设置本地文件长度
2.根据文件长度和线程数计算每条线程下载的数据长度和下载位置
3.使用HTTP的range字段指定每条线程从什么位置下载,到什么位置停止
4.保存文件。使用RandomAccessFile类指定每条线程从本地文件的什么位置开始写入数据。
首先先看一下依赖
compile 'com.youth.banner:banner:1.4.9' compile 'com.github.bumptech.glide:glide:3.7.0' compile 'com.jcodecraeer:xrecyclerview:1.3.2' compile 'io.reactivex:rxjava:1.0.14' compile 'io.reactivex:rxandroid:1.0.1' compile 'com.squareup.retrofit2:retrofit:2.0.2' compile 'com.squareup.okhttp3:okhttp:3.1.2' compile 'com.squareup.retrofit2:converter-gson:2.0.2' compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
用MVP模式首先看View层
接口类public interface IDialogView { public void showDialog();}
再看MODEL层
接口类public interface IDownLoadModel { public IDataView downLoad();}
public class DownLoadModel implements IDownLoadModel { @Override public IDataView downLoad() { Retrofit retrofit=new Retrofit.Builder() .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .baseUrl("http://10.0.2.2:8080/") .build(); IDataView dataView = retrofit.create(IDataView.class); return dataView; }}
PRESENTER层
public abstract class BaseActivity<T extends IDataPresenter> extends AppCompatActivity { public T presenter; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); createPresenter(); } public abstract void createPresenter(); @Override protected void onDestroy() { super.onDestroy(); if (presenter!=null){ presenter.detach(); } }}
public interface IDataPresenter<T> { public void attach(T view); public void detach();}
public class DownLoadPresenter implements IDataPresenter<IDialogView> { DownLoadModel model; SoftReference<IDialogView> softView; public DownLoadPresenter(IDialogView view) { attach(view); model = new DownLoadModel(); } public void getDataLength(final String downLoadUrl, final String path, final long threadNum) { model.downLoad().getFileLength(downLoadUrl) .subscribeOn(Schedulers.io()) .observeOn(Schedulers.io()) .subscribe(new Observer<ResponseBody>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(ResponseBody responseBody) { long length = responseBody.contentLength(); DownLoadTask.getDownLoadData(DownLoadPresenter.this, downLoadUrl, path, length, threadNum); } }); } public void getDownLoadFile(String downLoadUrl, String range, final File file, final long startPosition) { model.downLoad().downLoadFile(downLoadUrl, range) .subscribeOn(Schedulers.io()) .observeOn(Schedulers.io()) .subscribe(new Observer<ResponseBody>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(ResponseBody responseBody) {// Log.i("+++++++++++++++++", "onResponse: "+response.body().contentLength()); BufferedInputStream bis = new BufferedInputStream(responseBody.byteStream()); try { RandomAccessFile raf = new RandomAccessFile(file, "rwd"); raf.seek(startPosition); byte[] buff = new byte[1024 * 8]; int len = 0; while ((len = bis.read(buff)) != -1) { raf.write(buff, 0, len); } } catch (Exception e) { e.printStackTrace(); } } }); } @Override public void attach(IDialogView view) { softView = new SoftReference<IDialogView>(view); } @Override public void detach() { softView.clear(); }}
public interface IDataView { @Streaming @POST("{fileName}") Observable<ResponseBody> getFileLength(@Path("fileName") String fileName); @Streaming @POST("{fileName}") Observable<ResponseBody> downLoadFile(@Path("fileName") String fileName, @Header("Range") String range);}
public class DownLoadThread{ private String downLoadUrl; private String path; private long threadNum; private DownLoadPresenter presenter; public DownLoadThread(String downLoadUrl, String path, long threadNum,DownLoadPresenter presenter) { this.downLoadUrl = downLoadUrl; this.path = path; this.threadNum = threadNum; this.presenter=presenter; } public void show(){ presenter.getDataLength(downLoadUrl,path,threadNum); }}
public class DownLoadFileThread extends Thread { DownLoadPresenter presenter; private String downLoadUrl; private String range; private File file; private long startPosition; public DownLoadFileThread(DownLoadPresenter presenter, String downLoadUrl, String range, File file, long startPosition) { this.presenter = presenter; this.downLoadUrl = downLoadUrl; this.range = range; this.file = file; this.startPosition = startPosition; } @Override public void run() { presenter.getDownLoadFile(downLoadUrl,range,file,startPosition); }}
public class DownLoadTask { public static void getDownLoadData(DownLoadPresenter presenter,String downLoadUrl, String path, long length, long threadNum){ File file=new File(path); if (!file.exists()){ try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } long blockSize=length/threadNum; for (int i = 0; i < threadNum; i++) { long startPosition=blockSize*i; if (i==threadNum-1){ blockSize=length-blockSize*(threadNum-1); Log.i("+++++++++++", "getDownLoadData: "+blockSize); } String range = "bytes=" + startPosition + "-" + (startPosition + blockSize - 1); Log.i("++++++++++++++", "downLoadTask: "+startPosition+"-----"+(startPosition+blockSize-1)); new DownLoadFileThread(presenter,downLoadUrl,range,file,startPosition).start(); } }}
public class MainActivity extends BaseActivity<DownLoadPresenter> implements IDialogView { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initData(); } private void initData() { showDialog(); Log.i("---------", "initData: "+presenter); } @Override public void createPresenter() { presenter=new DownLoadPresenter(this); } @Override public void showDialog() { Log.i("==============", "initData: "+presenter); AlertDialog.Builder builder=new AlertDialog.Builder(this); builder.setTitle("是否更新") .setMessage("你太low了,赶快更新") .setNegativeButton("取消",null) .setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { new DownLoadThread("QQ.apk",getCacheDir()+"/qq.apk",5,presenter).show(); } }).show(); }}
阅读全文
0 0
- MVP Retrofit多线程下载
- Retrofit+RxJava+Mvp实现多线程视频下载
- Retrofit多线程下载
- Retrofit+多线程下载
- Retrofit多线程断点下载
- MVP+ReRxGreenDao多线程下载
- MVP + Retrofit
- RxJava和retrofit实现多线程下载
- 多线程下载,安装,Rxjava+okhttp+ Retrofit
- Retrofit多线程下载加进度条展示
- Retrofit+RXJava_多线程下载视频列表
- Retrofit+MVP模式学习
- MVP+Dagger2+Retrofit+Rxjava
- Retrofit实践(MVP+RxJava)
- Rxjava+MVP+Retrofit强强联合
- MVP、Retrofit、RxJava、RxBus
- Rxjava+retrofit+mvp整合
- Android_RxJava + Retrofit + MVP雏形
- do文件的编写
- Bailian3195 最大公约数【数论】
- RecyclerView实现二级列表
- 云星数据---Apache Flink实战系列(精品版)】:Flink其他操作及内容004-flink的背压机制002
- mysql还可以这么玩
- MVP Retrofit多线程下载
- 深入浅析安卓动画体系
- JavaScript:关闭弹出窗口时刷新父窗口
- pymongo连接超时的做法
- 基于spring+quartz的分布式定时任务框架
- jquery中attr和prop的区别
- 创建者模式之简单工厂模式
- 在Linux服务器上部署javaweb项目
- Win10的Mac安装Oracle的血泪史