ReRxMvpGreenDao_断点续传

来源:互联网 发布:js分页原理 编辑:程序博客网 时间:2024/06/05 18:46

Retrofit:

public interface RetrofitZj {    /* @Streaming*//*大文件需要加入这个判断,防止下载过程中写入到内存中*//*    @GET    Observable<ResponseBody> download(@Header("RANGE") String start, @Url String url);*/        @Streaming        @GET        Observable<ResponseBody> download(@Header("RANGE") String start, @Url String url);}

public class RetrofitAPI {    private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder();    private static Retrofit.Builder builder =            new Retrofit.Builder()                    .baseUrl("http://result.eolinker.com/")                    .addConverterFactory(GsonConverterFactory.create())                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create());    public static <S> S createService(Class<S> serviceClass) {        Retrofit retrofit = builder.client(httpClient.build()).build();        return retrofit.create(serviceClass);    }}

Bean:

@Entitypublic class Bean {    @Id    private Long id;    @Property(nameInDb = "RANGE")    private Long range;    @Property(nameInDb = "START")    private Long start;    @Property(nameInDb = "END")    private Long end;    @Property(nameInDb = "ThREADNUM")    private String ThreadNum;}


DaoManager:

public class DBManager {    private static Context mContext;    private static DBManager instance;    BeanDao beanDao;    Bean bean;    private DBManager() {    }    public static DBManager getInstance(Context context) {        if (instance == null) {            instance = new DBManager();            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.beanDao = daoSession.getBeanDao();        }        return instance;    }    /** 添加数据 */    public void addToCityInfoTable(Bean item)    {        beanDao.insert(item);    }    /** 查询 */    /** 通过城市id查找其类型id */    public List<Bean> getCityInfoList(int threadNum) {        QueryBuilder<Bean> qb = beanDao.queryBuilder();        qb.where(BeanDao.Properties.ThreadNum.eq(threadNum));        List<Bean> list = qb.list();        Log.i("========", "getCityInfoList: " + list);        return list;    }    public void updateInfo(int id,long rang){        QueryBuilder<Bean> qb = beanDao.queryBuilder();        qb.where(BeanDao.Properties.ThreadNum.eq(id));        List<Bean> list = qb.list();        Bean bean2 = list.get(0);        bean2.setRange(rang);        beanDao.update(bean2);    }}


Model接口:

public interface IDownLoadModel {    void getData(String start, String url, String url2, GetCallback callback);    void setGetProgress(DownLoadModel.getProgress getProgress);    interface GetCallback {        void GetComplete(ResponseBody responseBody);    }    void stop();    void jixu();    void getProgress();}
Model实现类:

public class DownLoadModel implements IDownLoadModel {    private static final String DOWNLOAD_INIT = "1";    private static final String DOWNLOAD_ING = "2";    private static final String DOWNLOAD_PAUSE = "3";    public DownLoadModel.getProgress getProgress;    private String stateDownload = DOWNLOAD_ING;//当前线程状态    String url3 = "";    Context context;    private long l;    public DownLoadModel(Context context) {        this.context = context;    }    @Override    public void getData(String start, String url, final String url2, final GetCallback callback) {        this.url3 = url;        RetrofitAPI.createService(RetrofitZj.class).download(start, url3)                .subscribeOn(Schedulers.io())                .observeOn(AndroidSchedulers.mainThread())                .subscribe(new Observer<ResponseBody>() {                    @Override                    public void onCompleted() {                    }                    @Override                    public void onError(Throwable e) {                    }                    @Override                    public void onNext(ResponseBody responseBody) {                        l = responseBody.contentLength();                        Log.i("=====length=====", "onNext: " + l);                        downloadFile(l, url2);                    }                });    }    @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 (Exception 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<Bean> cityInfoList = DBManager.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;                Bean bean2 = new Bean();                bean2.setThreadNum(i + "");                bean2.setRange((long) 0);                bean2.setStart(startPosition);                bean2.setEnd(end);                DBManager.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;        RetrofitAPI.createService(RetrofitZj.class).download(range, url3)                .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) {                        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<Bean> cityInfoList = DBManager.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) {                                    //更新数据库                                    DBManager.getInstance(context).updateInfo(i, length2);                                    break;                                }                            }                        } catch (Exception e) {                            e.printStackTrace();                        } finally {                            if (bis != null) {                                try {                                    bis.close();                                } catch (Exception e) {                                    e.printStackTrace();                                }                            }                            if (raf != null) {                                try {                                    raf.close();                                } catch (Exception e) {                                    e.printStackTrace();                                }                            }                        }                    }                });    }    public void setGetProgress(DownLoadModel.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 IDownLoadView {    void getData(ResponseBody responseBody);    void getPro(long length);}

Presenter:

public class DownLoadPresenter implements BasePresenter<IDownLoadView> {    Context context;    SoftReference<IDownLoadView> softReference;    IDownLoadModel model;    public DownLoadPresenter(Context context,IDownLoadView view) {        this.context = context;        atteach(view);        model = new DownLoadModel(context);    }    public void down(final String start, final String url, final String url2) {        model.getData(start, url, url2, new IDownLoadModel.GetCallback() {            @Override            public void GetComplete(ResponseBody responseBody) {            }        });    }    public void stop(){        model.stop();    }    public void jixu(){        model.jixu();    }    public void setProgress(){        model.setGetProgress(new DownLoadModel.getProgress() {            @Override            public void getProgress_length(long l) {                softReference.get().getPro(l);            }        });    }    @Override    public void atteach(IDownLoadView view) {        softReference = new SoftReference<IDownLoadView>(view);    }    @Override    public void deatch() {        softReference.clear();    }}

Activity:

public class MainActivity extends BaseActivity<DownLoadPresenter> implements IDownLoadView, View.OnClickListener {    private String video_url;    String url = "http://ww.baidu.com.mp4";    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_main);        initView();//        Intent intent = getIntent();//        video_url = intent.getStringExtra("video_url");//        Log.i("11111111111111111", "onCreate: " + video_url);//        //  initPlayer();        presenter.setProgress();    }    @Override    public void createPresenter() {        presenter = new DownLoadPresenter(this, this);    }    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="下载" />    <Button        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" />