MVP+ReRxGreenDao多线程下载

依赖:

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值