MVP+ReRxGreenDao多线程下载
来源:互联网 发布:a计划软件 编辑:程序博客网 时间:2024/06/08 06:53
依赖:
GreenDao:
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.1'
apply plugin: 'org.greenrobot.greendao'
compile 'org.greenrobot:greendao:3.2.0'其他依赖:4
compile 'io.reactivex.rxjava2:rxjava:2.1.1' compile 'io.reactivex.rxjava2:rxandroid:2.0.1' //retrofit compile 'com.squareup.retrofit2:retrofit:2.2.0' //Gson converter compile 'com.squareup.retrofit2:converter-gson:2.2.0' //RxJava2 Adapter compile 'com.squareup.retrofit2:adapter-rxjava2:2.2.0' //okhttp compile 'com.squareup.okhttp3:okhttp:3.6.0' implementation 'com.android.support:recyclerview-v7:26.1.0' compile 'com.youth.banner:banner:1.4.9' compile 'com.github.bumptech.glide:glide:3.7.0' compile 'com.facebook.fresco:fresco:0.11.0'
Retrofit注解:
public interface GetInterface { @Streaming @GET//我们在下载的时候,需要加入Range值,用来标记下载的点 Observable<ResponseBody> download(@Header("RANGE") String start, @Url String url);}封装Retrofit:
public class BaseService {//实现ok,在很多应用的时候,会出现添加拦截器请求数据 private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); private static Retrofit.Builder builder = new Retrofit.Builder()//Base.url 是我们自己定义的基路径 .baseUrl(Base.url)//支持GSON和RXJAVA .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create());//提供一个方法来实现retrofit的创建 public static <S> S createService(Class<S> serviceClass) { Retrofit retrofit = builder.client(httpClient.build()).build(); return retrofit.create(serviceClass); }}
Model接口:
public interface IDwonFile {//实现获取数据的方法,start开始的位置,url是我们请求的路径,url2是我们要缓冲的路径,GetCallback 是实现接口回调 void getData(String start, String url, String url2, GetCallback callback); interface GetCallback { void GetComplete(ResponseBody responseBody); }//暂停的方法 void stop();//继续的方法 void jixu();//获取进度条值的方法 void getProgress();}
Model实现类:
public class IdownModel implements IDwonFile { private static final String DOWNLOAD_INIT = "1"; private static final String DOWNLOAD_ING = "2"; private static final String DOWNLOAD_PAUSE = "3"; public getProgress getProgress; private String stateDownload = DOWNLOAD_ING;//当前线程状态 String url3 = ""; Context context; private long l; public IdownModel(Context context) { this.context = context; } @Override public void getData(String start, String url, final String url2, final GetCallback callback) { this.url3 = url; BaseService.createService(GetInterface.class).download(start, url3) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<ResponseBody>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(ResponseBody responseBody) { l = responseBody.contentLength(); Log.i("=====length=====", "onNext: " + l); downloadFile(l, url2); } @Override public void onError(Throwable e) { } @Override public void onComplete() { } }); } @Override public void stop() { stateDownload = DOWNLOAD_PAUSE; } @Override public void jixu() { stateDownload = DOWNLOAD_ING; } @Override public void getProgress() { } public void downloadFile(long length, String url2) { final File file = new File(url2); if (!file.exists()) { try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } int threadNum = 5; long blockSize = length / threadNum; long startPosition = 0; long end = 0;// //四舍五入--- 让一个数字+0。5在四舍五入 就变成 向上取整 //计算出下载块以后 创建线程执行下载操作 for (int i = 0; i < threadNum; i++) { List<Bean2> cityInfoList = DBHelper.getInstance(context).getCityInfoList(i); if (cityInfoList.size() > 0) { Long range = cityInfoList.get(0).getRange(); Long start = cityInfoList.get(0).getStart(); Long end1 = cityInfoList.get(0).getEnd(); startPosition = range + start; end = end1; Log.i("=====", "downloadFile: " + startPosition + "==" + end); } else { startPosition = blockSize * i; //让最后一个线程下载的大小是正好的, 总长度 - 除了最后一个块的大小和 if (i == threadNum - 1) { blockSize = length - blockSize * (threadNum - 1); } end = startPosition + blockSize - 1; Bean2 bean2 = new Bean2(); bean2.setThreadNum(i + ""); bean2.setRange((long) 0); bean2.setStart(startPosition); bean2.setEnd(end); DBHelper.getInstance(context).addToCityInfoTable(bean2); } downloadTask(startPosition, file, end, length, i); } } public void downloadTask(final long startPosition, final File file, long end, final long length, final int i) { //计算开始位置 String range = "bytes=" + startPosition + "-" + end; BaseService.createService(GetInterface.class).download(range, url3) .subscribeOn(Schedulers.io()) .observeOn(Schedulers.io()) .subscribe(new Observer<ResponseBody>() { @Override public void onSubscribe(Disposable d) { } @Override public void onNext(ResponseBody responseBody) { BufferedInputStream bis = null; RandomAccessFile raf = null; try { bis = new BufferedInputStream(responseBody.byteStream()); raf = new RandomAccessFile(file, "rwd"); raf.seek(startPosition); byte[] buff = new byte[1024 * 8]; int len = 0; List<Bean2> cityInfoList = DBHelper.getInstance(context).getCityInfoList(i); long length2 = cityInfoList.get(0).getRange(); Log.i("=====继续length2=======", "onNext: " + length2); while ((len = bis.read(buff)) != -1) { Log.i("===循环继续====", "onNext: "); if (stateDownload == DOWNLOAD_ING) { Log.i("===继续下载====", "onNext: "); length2 += len; raf.write(buff, 0, len); handler.sendEmptyMessage((int) len); } else if (stateDownload == DOWNLOAD_PAUSE) { //更新数据库 DBHelper.getInstance(context).updateInfo(i, length2); break; } } } catch (IOException e) { e.printStackTrace(); } finally { if (bis != null) { try { bis.close(); } catch (IOException e) { e.printStackTrace(); } } if (raf != null) { try { raf.close(); } catch (IOException e) { e.printStackTrace(); } } } } @Override public void onError(Throwable e) { } @Override public void onComplete() { } }); } public void setGetProgress(IdownModel.getProgress getProgress) { this.getProgress = getProgress; } public interface getProgress { void getProgress_length(long l); } private long downloadedSize = 0; @SuppressLint("HandlerLeak") Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); //每次每个线程回来的长度 int length = msg.what; synchronized (this) { downloadedSize += length; } getProgress.getProgress_length(downloadedSize * 100 / l); Log.i("downloadedSize", "handleMessage: " + downloadedSize); Log.i("百分比", "handleMessage: " + downloadedSize * 100 / l); } };}View接口:public interface IDownView { void getData(ResponseBody responseBody); void getPro(long length);}
P层:public class DownPresenter implements IPresenter<IDownView> { SoftReference<IDownView> srf; IdownModel model; Context context; public DownPresenter(IDownView view, Context context) { this.context = context; model = new IdownModel(context); attch(view); } public void down(final String start, final String url, final String url2) { model.getData(start, url, url2, new IDwonFile.GetCallback() { @Override public void GetComplete(ResponseBody responseBody) { } }); } public void stop(){ model.stop(); } public void jixu(){ model.jixu(); } public void setProgress(){ model.setGetProgress(new IdownModel.getProgress() { @Override public void getProgress_length(long l) { srf.get().getPro(l); } }); } @Override public void attch(IDownView view) { srf = new SoftReference<IDownView>(view); } @Override public void disattch() { }}
基类:public interface IPresenter<T> { void attch(T view); void disattch();}public abstract class BaseActivity<T extends IPresenter> extends AppCompatActivity { public T presenter; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); createPresnter(); } protected abstract void createPresnter(); protected abstract void init();}
GreenDao:public class DBHelper { private static Context mContext; private static DBHelper instance; Bean2Dao bean2Dao; Bean2 bean; private DBHelper() { } public static DBHelper getInstance(Context context) { if (instance == null) { instance = new DBHelper(); if (mContext == null) { mContext = context; } // 数据库对象 // 数据库对象 DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(mContext, "student.db", null); DaoMaster daoMaster = new DaoMaster(devOpenHelper.getWritableDb()); DaoSession daoSession = daoMaster.newSession(); instance.bean2Dao = daoSession.getBean2Dao(); } return instance; } /** 添加数据 */ public void addToCityInfoTable(Bean2 item) { bean2Dao.insert(item); } /** 查询 */ /** 通过城市id查找其类型id */ public List<Bean2> getCityInfoList(int threadNum) { QueryBuilder<Bean2> qb = bean2Dao.queryBuilder(); qb.where(Bean2Dao.Properties.ThreadNum.eq(threadNum)); List<Bean2> list = qb.list(); Log.i("========", "getCityInfoList: " + list); return list; } public void updateInfo(int id,long rang){ QueryBuilder<Bean2> qb = bean2Dao.queryBuilder(); qb.where(Bean2Dao.Properties.ThreadNum.eq(id)); List<Bean2> list = qb.list(); Bean2 bean2 = list.get(0); bean2.setRange(rang); bean2Dao.update(bean2); }}
实现:public class OtherActivity extends BaseActivity<DownPresenter> implements /*PlayerManager.PlayerStateListener,*/ View.OnClickListener, IDownView { private String video_url; private Button mBtn; public static long MAX_SIZE; private VideoView mWb; private Button mStopBtn; private Button mJxBtn; private ProgressBar mPb; private TextView mTv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_other); initView(); Intent intent = getIntent(); video_url = intent.getStringExtra("video_url"); Log.i("11111111111111111", "onCreate: " + video_url); presenter.setProgress(); } @Override protected void createPresnter() { presenter = new DownPresenter(this, this); } @Override protected void init() { } private void initView() { mBtn = (Button) findViewById(R.id.btn); mBtn.setOnClickListener(this); mStopBtn = (Button) findViewById(R.id.btn_stop); mStopBtn.setOnClickListener(this); mJxBtn = (Button) findViewById(R.id.btn_jx); mJxBtn.setOnClickListener(this); mPb = (ProgressBar) findViewById(R.id.pb); mTv = (TextView) findViewById(R.id.tv); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn: String url2 = getCacheDir() + "haha.mp4"; presenter.down(String.valueOf(0), url, url2); break; case R.id.btn_stop:// TODO 17/11/22 presenter.stop(); break; case R.id.btn_jx:// TODO 17/11/22 String url3 = getCacheDir() + "haha.mp4"; presenter.jixu(); presenter.down(String.valueOf(0), url, url3); break; default: break; } } @Override public void getData(ResponseBody responseBody) { } @Override public void getPro(long length) { mPb.setMax(100); mPb.setProgress((int) length); //mTv.setText(length+"%"); }}布局:<Button android:id="@+id/btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="下载" /> android:id="@+id/btn_stop" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/btn" android:text="暂停" /> <Button android:id="@+id/btn_jx" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/btn_stop" android:text="继续" /> <ProgressBar android:id="@+id/pb" style="@style/Base.Widget.AppCompat.ProgressBar.Horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@+id/btn_jx" /> <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_below="@+id/pb" android:layout_height="wrap_content" />
阅读全文
0 0
- MVP+ReRxGreenDao多线程下载
- MVP Retrofit多线程下载
- Retrofit+RxJava+Mvp实现多线程视频下载
- 利用网络框架和MVP多线程下载和断点续传
- 多线程下载
- 多线程下载
- 多线程下载
- 多线程下载
- 多线程下载
- 多线程下载
- 多线程下载
- 多线程下载
- 多线程下载
- 多线程下载
- 多线程下载
- 多线程下载
- 多线程下载
- 多线程下载
- 十 项目1(3)
- 河南新乡:从“诗经之乡”到“云之乡”
- ViewPager和RecyclerView缓存View的问题
- 使用Python判断质数(素数)的简单方法讲解
- angular与vue的较量
- MVP+ReRxGreenDao多线程下载
- 维系数字世界的真谛--“维谛技术发布会”隆重举行,开启网络能源新时代
- 支付宝内测版曝光:将很快支持这个功能!
- VS2015中编译snmp++及内存泄漏解决方法
- Spring Boot 集成Mybatis操作数据库
- 欢迎使用CSDN-markdown编辑器
- 注册表单验证
- Android中的Ninja简介
- Async接口类