OkHttp使用+文件的上传+断点续传

这里写图片描述

  • 普通的Get请求
case R.id.get:
     HttpManager.getInstance().getRequest(getUri,this);
     break;

//方法的回调  
@Override
    public void onFailure(Call call, IOException e) {//子线程
        Log.d("flag", "----------------->onFailure: ");
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        byte[] bytes = response.body().bytes();
        Log.d("flag", "------>onResponse: 获取图片字节长度: " +bytes.length);
        final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mImageView.setImageBitmap(bitmap);
                Log.d("flag", "------->run: 图片加载成功");
            }
        });
    }

为了方便调用请求,创建单例模式调用方法

public void getRequest(String url, Callback callback){
        Request request = new Request.Builder()
                .url(url)
                .build();
        mOkHttpClient.newCall(request).enqueue(callback);
    }

OkHttp是在子线程中,注意更新UI操作

  • POST请求
public void postRequest(String url, RequestBody requestBody, Callback callback){
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)//请求体,参数
                .build();
        mOkHttpClient.newCall(request).enqueue(callback);
    }
case R.id.post:

RequestBody requestBody = new FormBody.Builder()
                        .add("name","michael")
                        .add("age","25")
                        .add("tel","666")
                        .build();
                HttpManager.getInstance().postRequest(postUri,requestBody,this);

此处的回调方法依旧是Get请求当中的加载图片

  • 文件的上传(post类似,添加请求体)
//上传数据给服务器
public void uploadImage(String url, RequestBody uploadBody, Callback callback) {
        Request request = new Request.Builder()
                .url(url)
                .post(uploadBody)
                .build();
        mOkHttpClient.newCall(request).enqueue(callback);
    }

addFormDataPart(请求体)

case upload://上传数据给服务器,也是post请求,post请求有请求体,将文件包裹到请求体,进行上传
                //multipart/form-data 上传文件

                String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath()
                        + File.separator + "icon.jpg";

                File file = new File(path);
                RequestBody body = RequestBody.create(MediaType.parse("image/*"),file);

                RequestBody uploadBody = new MultipartBody.Builder()
                        .addFormDataPart("name","softpo")
                        .addFormDataPart("age","34")
                        .addFormDataPart("tel","0987654321")
                        .addFormDataPart("image","softpo.jpg",body)
                        .build();

                HttpManager.getInstance().uploadImage(uploadUri,uploadBody, new Callback() {
                    @Override
                    public void onFailure(Call call, IOException e) {
                        Log.d("flag", "----------------->onFailure: " +e.getMessage());
                    }
                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        Log.d("flag", "----------------->onResponse: " +response.body().string());
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(MainActivity.this, "文件上传成功", Toast.LENGTH_SHORT).show();
                            }
                        });
                    }
                });
                break;
  • 文件的断点续传

核心:
1.请求网址计算内容的总长度
2.创建线程池的对象
3.分配线程的执行长度(开始和结束)
4.根据开始和结束-添加addHeader请求头
5.根据Respose获取输入流,读取写入文件
6.接口回调,加载图片

case R.id.download_range:
            DownloadManager.getInstance().download(imageUrl,this);
                break;
public class DownloadManager {

    //线程池
    public static final int MAX_SIZE = 2;

    private ThreadPoolExecutor mThreadPoolExecutor = new ThreadPoolExecutor(
            MAX_SIZE,
            MAX_SIZE,
            60,
            TimeUnit.MILLISECONDS,
            new SynchronousQueue<Runnable>(),//线程管理队列
            new ThreadFactory() {
                AtomicInteger mAtomicInteger = new AtomicInteger();
                @Override
                public Thread newThread(Runnable r) {
                    //参数二区分线程
                    Thread thread =
                            new Thread(r,"Thread Number # "+mAtomicInteger.getAndIncrement());

                    return thread;
                }
            }
    );


    private static DownloadManager ourInstance = new DownloadManager();

    public static DownloadManager getInstance() {
        return ourInstance;
    }

    private DownloadManager() {
    }

    public void download(final String url, final Callback callback){

        HttpManager.getInstance().getRequest(url, new okhttp3.Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                callback.onFailure(e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //要下载内容的总长度
                long contentLength = response.body().contentLength();

                //多线程下载
                processDownload(url,contentLength,callback);
            }
        });
    }

    private void processDownload(String url, long contentLength, Callback callback) {
        int length = (int) (contentLength/MAX_SIZE);

        for (int i = 0; i < MAX_SIZE; i++) {//执行两次

            int start = i*length;
            //奇数:9  4.5  0-4 --- 4+
            //偶数:10  5   0-4 --- 4+
            int end = 0;
            //奇数偶数(类似)
            if(contentLength%2==1){
                end = (i+1)*length;
            }else {//偶数
                end = (i+1)*length-1;
            }
            mThreadPoolExecutor.execute(new DownloadRunnable(url,start,end,callback));
        }
    }
}

根据循环每个线程去执行start和end

public class DownloadRunnable implements Runnable {

    private String mUrl;
    private int mStart;
    private int mEnd;
    private Callback mCallback;

    public DownloadRunnable(String url, int start, int end, Callback callback) {
        this.mUrl = url;
        this.mStart = start;
        this.mEnd = end;
        this.mCallback = callback;
    }

    @Override
    public void run() {//子线程
        Response response = HttpManager.getInstance().asyncGetRangeBytes(mUrl, mStart, mEnd);
        try {
            InputStream is = response.body().byteStream();

            String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
                    .getAbsolutePath() + File.separator
                    + mUrl.substring(mUrl.lastIndexOf("/") + 1);

            File file = new File(path);

            RandomAccessFile randomAccessFile = new RandomAccessFile(file,"rwd");//rwd:可读可写可追加
            //!!!
            randomAccessFile.seek(mStart);
            //写数据
            int len = 0;
            byte[] buf = new byte[1024*8];
            while((len = is.read(buf))!=-1){
                randomAccessFile.write(buf,0,len);
            }
            //回调
            mCallback.onSuccess(file);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

HttpManager中创建获取RangeBytes的方法

  public Response asyncGetRangeBytes(String imageUrl,int start,int end){
        //断点获取服务器的数据
        Request request = new Request.Builder()
                .url(imageUrl)
                .addHeader("range","bytes="+start+"-"+end)//请求头
                .build();
        //execute OkHttp执行联网请求,下载数据
        try {
            return  mOkHttpClient.newCall(request).execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

接口回调,设置图片

@Override
    public void onFailure(String message) {
        Log.d("flag", "----------------->onFailure: 多线程下载失败");
    }

    @Override
    public void onSuccess(File file) {
        Log.d("flag", "----------------->onSuccess: 多线程下载图片成功");
        final Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mImageView.setImageBitmap(bitmap);
            }
        });

    }

所用的接口

public interface Callback {
    void onFailure(String message);
    void onSuccess(File file);
}

代码已经上传:

http://download.csdn.net/detail/weixin_37263797/9835223

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值