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

来源:互联网 发布:德川幕府 知乎 编辑:程序博客网 时间:2024/05/22 01:45

这里写图片描述

  • 普通的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

2 0
原创粉丝点击