ReRxMvpGreenDao_断点续传

Retrofit:

public interface RetrofitZj {

    /* @Streaming*//*大文件需要加入这个判断,防止下载过程中写入到内存中*//*
    @GET
    Observable download(@Header("RANGE") String start, @Url String url);*/
        @Streaming
        @GET
        Observable 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 createService(Class serviceClass) {
        Retrofit retrofit = builder.client(httpClient.build()).build();
        return retrofit.create(serviceClass);
    }
}

Bean:

@Entity
public 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 getCityInfoList(int threadNum) {
        QueryBuilder qb = beanDao.queryBuilder();
        qb.where(BeanDao.Properties.ThreadNum.eq(threadNum));
        List list = qb.list();
        Log.i("========", "getCityInfoList: " + list);
        return list;
    }

    public void updateInfo(int id,long rang){
        QueryBuilder qb = beanDao.queryBuilder();
        qb.where(BeanDao.Properties.ThreadNum.eq(id));
        List 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() {
                    @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 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() {
                    @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 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 {

    Context context;
    SoftReference 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(view);
    }

    @Override
    public void deatch() {
        softReference.clear();
    }
}

Activity:

public class MainActivity extends BaseActivity 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+"%");
    }


}

布局:

    




你可能感兴趣的:(多线程)