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

xiaoxiao2021-02-28  40

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

转载请注明原文地址: https://www.6miu.com/read-59967.html

最新回复(0)