OkHttp大文件下载

系统自带的DownloadManager下载

        IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
        mReceiver = new Receiver();
        registerReceiver(mReceiver, filter);
    //系统提供的DownloadManager来下载
    private void startDownload() {
        final DownloadManager downloadManager = (DownloadManager)getSystemService(Context.DOWNLOAD_SERVICE);
        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(DOWNLOAD_URL));
        request.setDestinationInExternalFilesDir(this, null, "yixin.apk");
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
        request.setMimeType("application/vnd.android.package-archive");
        request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);

        mDownloadId = downloadManager.enqueue(request);
    }
    public class Receiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            long reference = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
            if (mDownloadId == reference) {
                DownloadManager.Query query = new DownloadManager.Query();
                query.setFilterById(reference);

                Cursor cursor = ((DownloadManager)(getSystemService(
                        Context.DOWNLOAD_SERVICE))).query(query);
                if (cursor.moveToFirst()) {
                    String fileName = cursor.getString(cursor.getColumnIndex(
                            DownloadManager.COLUMN_LOCAL_FILENAME));
                    mTvResult.setText(fileName);
                }
                cursor.close();
            }
        }
    }

使用OkHttp下载

分片下载
    获取文件大小
    分片下载数据
    是否完成
    //OkHttpClient配置
    private OkHttpClient getClient() {
        if (null == mHttpClient) {
            mHttpClient = new OkHttpClient.Builder()
                    .connectTimeout(30, TimeUnit.SECONDS)
                    .readTimeout(30, TimeUnit.SECONDS)
                    .writeTimeout(30, TimeUnit.SECONDS).build();
        }
        return mHttpClient;
    }
   private static final String DOWNLOAD_URL = "http://yixin.dl.126.net/update/installer/yixin.apk";

    private Button mBtnDownloadSelf;
    private ProgressBar mProgressBar;

    private OkHttpClient mHttpClient;

    private DownloadState mState = DownloadState.PENDING;

    private int mTotal;

    private static final int DELTA = 256 * 1024;

    private OutputStream mDstOutputStream;

    private int mCurrentDownload;

    private enum DownloadState {
        PENDING,
        DOWNLOADING,
        PAUSE,
        DONE
    }
   @Override
    public void onClick(View v) {
        if (R.id.btn_download_by_system == v.getId()) {
//            startDownload();
        } else if (R.id.btn_download_self == v.getId()) {
            switch (mState) {
                case PENDING:
                    startDownloadSelf();
                    mState = DownloadState.DOWNLOADING;
                    break;
                case DOWNLOADING:
                    mState = DownloadState.PAUSE;
                    break;
                case PAUSE:
                    mState = DownloadState.DOWNLOADING;
                    downloadRange(mCurrentDownload);
                    break;
            }
            refreshButton();
        }
    }
    private void refreshButton() {
        switch (mState) {
            case DOWNLOADING:
                mBtnDownloadSelf.setText(R.string.pause);
                break;
            case PENDING:
                mBtnDownloadSelf.setText(R.string.start_download);
                break;
            case PAUSE:
                mBtnDownloadSelf.setText(R.string.resume);
                break;
            case DONE:
                mBtnDownloadSelf.setText(R.string.done);
                break;
        }
    }
    //开始下载
    private void startDownloadSelf() {
        getFileLength(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    //获取下载文件长度
                    mTotal = Integer.valueOf(response.header("Content-Length"));
                    mDstOutputStream = new FileOutputStream(getExternalFilesDir(null).getAbsolutePath() + "/yixin.apk");
                    downloadRange(0);
                }
            }
        });
    }

    //获取文件大小
    private void getFileLength(Callback callback) {
        Request request = new Request.Builder()
                .url(DOWNLOAD_URL)
                .method("HEAD", null).build();

        getClient().newCall(request).enqueue(callback);
    }

    private void downloadRange(int start) {
        //分段下载,range参数将文件进行分片
        Request request = new Request.Builder()
                .url(DOWNLOAD_URL)
                .addHeader("range", "bytes=" + start + "-" + Math.min(start + DELTA, mTotal)).build();

        getClient().newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful() && mState == DownloadState.DOWNLOADING) {
                    final byte[] bytes = response.body().bytes();
                    mDstOutputStream.write(bytes);
                    mCurrentDownload += bytes.length;
                    mProgressBar.post(new Runnable() {
                        @Override
                        public void run() {
                            int progress = (int)(mCurrentDownload * 1.0 / mTotal * 100);
                            mProgressBar.setProgress(progress);

                            if (100 == progress) {
                                mState = DownloadState.DONE;
                                refreshButton();
                            }
                        }
                    });

                    if (mCurrentDownload >= mTotal) {
                        mDstOutputStream.flush();
                        mDstOutputStream.close();
                        return;
                    }

                    downloadRange(mCurrentDownload);
                }
            }
        });
    }

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