OKhttp使用入门篇
2016-04-07 12:11
435 查看
OKhttp使用入门篇
Okhttp是当下非常流行的网络框架,是相对比较成熟的解决方案,本文主要作为学习笔记之用:支持HTTP2/SPDY黑科技
socket自动选择最好路线,并支持自动重连
拥有自动维护的socket连接池,减少握手次数
拥有队列线程池,轻松写并发
拥有Interceptors轻松处理请求与响应(比如透明GZIP压缩,LOGGING)
基于Headers的缓存策略
1.同步GET
访问网络必须在子线程进行,更新UI需要在主线程new Thread(new Runnable() { @Override public void run() { try { //构建方式有2种,任选其一就行 OkHttpClient client = new OkHttpClient();//方式1 // OkHttpClient client1=new OkHttpClient.Builder().build();//方式2 Request request = new Request.Builder().url( "你的url").get().build();//创建请求 //通过请求获取回调 Call call = client.newCall(request); //执行请求 Response response = call.execute(); // byte[] bytes = response.body().bytes();//通过获取字节数组方式获取内容 // final String str = new String(bytes, "utf-8"); final String str=response.body().string();//获取字符串方式 //主线程更新UI runOnUiThread(new Runnable() { @Override public void run() { “这里使用你获取的str进行一些UI操作” } }); } catch (IOException e) { e.printStackTrace(); } } }).start();//记得开启线程 } });
2异步GET
其他没什么区别,就是多了一句话 client.newCall(request).enqueue(new Callback() )而已,会自动重写两个方法。只需要填入你后续需要进行的操作就可以了,okhttp会帮我们开线程,所以,onFailure跟onResponse都是在子线程里try { OkHttpClient client = new OkHttpClient();//方式1 // OkHttpClient client1=new OkHttpClient.Builder().build();//方式2 Request request = new Request.Builder().url("http://192.168.56" + ".1:10086/oschina/list/tweet_list/page0.xml").get().build(); //创建请求 client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { runOnUiThread(new Runnable() { @Override public void run() { textView.setText("233"); } }); } }); } catch (Exception e) { e.printStackTrace(); }
3文件上传(post请求)
这一步跟异步请求唯一不同的一点就是设置了请求体的内容,就是那么两段话RequestBody fileBody=RequestBody.create(MediaType.parse(“application/octet-stream”), file);
创建混合请求体,可以同时传多个数据
RequestBody body=new MultipartBody.Builder()
通过post(body)上传,具体代码如下:
File file=new File(getCacheDir().getPath(),"/icon_my_message.png"); RequestBody fileBody=RequestBody.create(MediaType.parse ("application/octet-stream"), file);//使用MediaType来进行来转换文件内容到请求体中 RequestBody body=new MultipartBody.Builder()//设置请求体 .setType(MultipartBody.FORM)//设置 .addFormDataPart("name", "Tom")//设置用户名,这个根据你服务器来定 .addFormDataPart("hehe", "xixi.jpg", fileBody)//设置你要传送的文件,中间是你自己定义的文件名 .build();//开始构建 OkHttpClient client=new OkHttpClient.Builder().build(); Request request=new Request.Builder() .url("http://192.168.56.1:10086/android-corebase-day11/upload") .post(body) .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { runOnUiThread(new Runnable() { @Override public void run() { “若需要更新UI,在这里进行” } }); } @Override public void onResponse(Call call, Response response) throws IOException { runOnUiThread(new Runnable() { @Override public void run() { “若需要更新UI,在这里进行” } }); } });
4.文件下载
这个异常简单,就不细说了,操作下载的文件可根据需要转换为自己所要的格式进行操作,在回调里,如果需要改变UI,记得扔到主线程操作,回调里面重写的方法都是在子线程里,切记。final OkHttpClient client=new OkHttpClient.Builder().build(); final Request request=new Request.Builder() .url("http://192.168.56.1:10086/oschina/list/tweet_list/page0.xml") .get() .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Log.e("itcast","失败了"); } @Override public void onResponse(Call call, Response response) throws IOException { File file=new File(filepath+"/aaa.xml"); FileOutputStream fos=new FileOutputStream(file); InputStream is=response.body().byteStream(); byte[] bt=new byte[1024]; int len=0; while((len=is.read(bt))!=-1) { fos.write(bt, 0, len); } fos.close(); } });
5.文件上传,带进度条的
这里我用了系统自带的进度条对话框,并且已经封装成一个工具类//首先创建一个进度条 final ProgressDialog progressDialog=new ProgressDialog(context); progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressDialog.setCancelable(false); progressDialog.show(); new Thread(new Runnable() { @Override public void run() { UpLoadUtil.postFileWithProgress(context,url,filepath,filename,progressDialog);//调用者一个方法就可以了,5个参数分别的意义是context上下文对象,url你需要的访问的链接,filepath你要上传的文件路径,filename你上传的文件名,progressDialog你设置的进度条对话框,根据需要可改成其他样式 } }).start();
下面是完整的上传实现类。注释写了挺久。
public class UpLoadUtil { interface ProgressRequestListener{ //定义接口监听文件上传进度,参数意义:1已读数据,2全部数据,3是否结束 void onRequestProgress(long bytesWritten, long contentLength, boolean done); } static class ProgressRequestBody extends RequestBody { //自定义请求体,继承请求体 private final RequestBody requestBody;//请求体 private final ProgressRequestListener progressListener;//回调自定义接口 private BufferedSink bufferedSink;//包装完成的bufferedsink(缓存池) //提供上传进度构造方法 public ProgressRequestBody(RequestBody requestBody, ProgressRequestListener progressListener) { this.requestBody = requestBody; this.progressListener = progressListener; } //返回MediaType,传入的requestBody中获取,(如"application/octet-stream") @Override public MediaType contentType() { return requestBody.contentType(); } //重写全部长度方法,从请求体中获取文件总长 @Override public long contentLength() throws IOException { long length=requestBody.contentLength(); return length; } @Override public void writeTo(BufferedSink sink) throws IOException { if (bufferedSink==null){ //包装,调用自定义的sink方法 bufferedSink= Okio.buffer(sink(sink)); } //将缓存写入到请求体重 requestBody.writeTo(bufferedSink); //释放缓存。避免最后一部分数据可能不会被写入 bufferedSink.flush(); } private Sink sink(Sink sink){ //正在上传的文件 return new ForwardingSink(sink) { //当前写入字节数 long bytesWritten=0L; //总字节长度,避免多次调用contentLength()方法 long contentLength=0L; @Override public void write(Buffer source, long byteCount) throws IOException { super.write(source, byteCount); if (contentLength==0){ //获得contentLength的值,后续不再调用 contentLength=contentLength(); } //增加当前写入的字节数 bytesWritten+=byteCount; progressListener.onRequestProgress(bytesWritten,contentLength, bytesWritten==contentLength); } }; } } public static void postFileWithProgress(final Context context, String url, String filePath, String fileName, final ProgressDialog progressDialog){ //url就是上传到服务器地址,upload会处理上传的请求体,需要部署并开启servlet // String url= "http://192.168.56.1:10086/android-corebase-day11/upload"; ProgressRequestListener requestListener=new ProgressRequestListener() { // 重写接口方法,打印进度 @Override public void onRequestProgress(final long bytesWritten, final long contentLength, boolean done) { // Log.e("--contentLength--", "----" + contentLength); // Log.e("--bytesRead--", "----" + bytesWritten); Log.e("--进度--",bytesWritten*100/contentLength+"%"); ((Activity)context).runOnUiThread(new Runnable() { @Override public void run() { if (contentLength==bytesWritten){ progressDialog.dismiss(); Toast.makeText(context,"上传成功",Toast.LENGTH_LONG).show(); }else { progressDialog.setMax((int) contentLength); progressDialog.setProgress((int) bytesWritten); } } }); } }; //给出文件地址context.getCacheDir().getPath(),"/icon_my_message.png" File file=new File(filePath+"/"+fileName); //创建客户端 OkHttpClient client=new OkHttpClient.Builder().build(); //创建混合请求体。上传者addFormDataPart("name","tom")这里是上传者是tom根据filename //后缀判断,xixi.jpg后缀是jpg,服务端会以流的形式写入到服务端指定的文件夹中 //以流的形式将文件读取到fileBody中 RequestBody fileBody=RequestBody.create(MediaType.parse("application/octet-stream"),file); RequestBody body=new MultipartBody.Builder() .setType(MultipartBody.FORM) .addFormDataPart("name","tom") .addFormDataPart("hehe",fileName,fileBody)//"xixi.jpg" .build(); //创建ProgressRequestBody对象,带进度的请求体 RequestBody bodyWithProgress=new ProgressRequestBody(body,requestListener); // 创建请求 Request request=new Request.Builder() .url(url)//请求地址 .post(bodyWithProgress)//请求体 .build(); // 执行请求 client.newCall(request).enqueue(new Callback() { @Override public void onResponse(Call call, Response response) throws IOException { Log.e("MainActivity", response.body().string()); ((Activity)context).runOnUiThread(new Runnable() { @Override public void run() { Log.e("itcast","成功"); } }); } @Override public void onFailure(Call call, IOException e) { ((Activity)context).runOnUiThread(new Runnable() { @Override public void run() { Log.e("itcast","失败"); } }); } }); } }
总结:Okhttp简单易用,还有个带进度条的文件下载,这个就不细说了,上传的时候,还需要开启服务器的servlet进行操作,不然是传不上去的。。
相关文章推荐
- 高性能 TCP & UDP 通信框架 HP-Socket v3.4.1 正式发布
- 高性能 TCP & UDP 通信框架 HP-Socket v3.4.1 正式发布
- 土耳其网络实名5000W公民数据泄露
- MBProgressHUD框架的使用:https://github.com/jdg/MBProgressHUD
- zz:Android使用HttpPost向服务器发送Json数据
- zz:Android中发送Http请求实例(包括文件上传、servlet接收)
- TCP快速重传与快速恢复原理分析
- C#中调用Matlab人工神经网络算法实现手写数字识别
- zz:Android中发送Http请求实例(包括文件上传、servlet接收)
- zz:android网络开发详解
- boost asio异步读写网络聊天程序client 实例具体解释
- HTTP协议之无连接与无状态
- ajax 调用接口 C# 调用接口 PostHttpResponse 类
- StringBuffer类和String类(原文地址 : http://www.cnblogs.com/springcsc/archive/2009/12/03/1616330.html)
- 4.4.2 single_server_accept_inet函数:接收网络请求
- Func:统一网络控制器
- Func:统一网络控制器
- php 单线程 (http://bbs.csdn.net/topics/390778072)
- iOS9出来了,http不管用
- http协议简述