OKHttp 使用
2015-09-10 11:30
1246 查看
Android网络请求框架很多,为什么我选择的是Okhttp?
也许是不经意之间听到Android4.4的源码里面都用了她,又或者是她支持Google开发的SPDY协议,
又或者她来自鼎鼎大名的Square?
其实我也不知道,就想试一下;
在使用过程出现很多问题,相比于那些成熟的网络框架, 体现出来的是OkHttp相当于HttpClient和HttpURLConnection这种底层一点的,而其余的所有网络请求框架基本都是对HttpClient和HttpURLConnection封装,所以很多框架都在网络请求上可以用她来作为底层,Volley可以用她再来作为底层的网络请求,Fresco也可以,在Fresco的一个Demo中,Fresco+OkHttp速度最快,不知道是不是偶然,我自己测试是如此,等等其他很多。
在当前项目中使用的是这个,所以为了方便处理,做了一些封装,有自己的封装也有参考网上资料的,整合力一下。
先看几个请求方式和请求结果 gif是按照顺序来操作
文件上传的log细节
文件下载的log细节
先看看对OkHttp使用的封装
这里是一些OKHttp使用中的一些操作
//如果json body这么构建
其实很简单 只是新增一个接口 让其可以UI更新
其实大家看到了 上面有两个方法一个是 下载的进度显示和一个上传的进度显示 这是以前使用的 也能达到效果
后面有一天在微博看到相关的封装 对已上传和下载的进度显示 就集成进来项目中
红线部分是对于上传和下载的进度显示的类和接口
这里的话 去看这个吧 我是从这个看到的写的挺好的
http://blog.csdn.net/sbsujjbcy/article/details/48194701
或者这个也行 官方的demo
https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/com/squareup/okhttp/recipes/Progress.java
然后看看在整个项目中的一些设置
有BaseActivity的ondestyoy中的 请求取消
实际运用
/**
* 数据获取Get请求
*/
/**
* 数据上传 Post请求
*/
/**
* 图片下载
*/
/**
* 图文上传
*/
//数据的显示
以上就是四个例子的使用方法
关于Json的上传和cookie的使用在OkHttpUtil的注释里面有介绍
因为我写demo的效果都是用的公司的接口 所以上面把接口都给取消 需要的自己把接口加上去才能使用
demo上传到http://download.csdn.net/detail/liubo080852/9094387
有需要的可以下载哈
也许是不经意之间听到Android4.4的源码里面都用了她,又或者是她支持Google开发的SPDY协议,
又或者她来自鼎鼎大名的Square?
其实我也不知道,就想试一下;
在使用过程出现很多问题,相比于那些成熟的网络框架, 体现出来的是OkHttp相当于HttpClient和HttpURLConnection这种底层一点的,而其余的所有网络请求框架基本都是对HttpClient和HttpURLConnection封装,所以很多框架都在网络请求上可以用她来作为底层,Volley可以用她再来作为底层的网络请求,Fresco也可以,在Fresco的一个Demo中,Fresco+OkHttp速度最快,不知道是不是偶然,我自己测试是如此,等等其他很多。
在当前项目中使用的是这个,所以为了方便处理,做了一些封装,有自己的封装也有参考网上资料的,整合力一下。
先看几个请求方式和请求结果 gif是按照顺序来操作
文件下载的log细节
先看看对OkHttp使用的封装
public class OkHttpUtil { public static final OkHttpClient mOkHttpClient = new OkHttpClient(); static { mOkHttpClient.setConnectTimeout(30, TimeUnit.SECONDS); mOkHttpClient.setWriteTimeout(20, TimeUnit.SECONDS); mOkHttpClient.setReadTimeout(30, TimeUnit.SECONDS); } //自定义接口 目的是在调用的地方可以直接更新UI public interface MyCallBack { void onFailure(Request request, IOException e); void onResponse(String json); } //配置OKHttp的Cookie策略,有些地方需要做一些cookie相关的操作 public static void setCookie(CookieManager cookieManager) { cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ALL); mOkHttpClient.setCookieHandler(cookieManager); } public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); /** * 异步回调方式 请求 自定义回调接口 结果运行在UI线程 */ public static void postData2Server(final Activity activity, Request request, final MyCallBack myCallBack) { final String url = request.urlString(); try { mOkHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(final Request request, final IOException e) { if (activity == null) { return; } activity.runOnUiThread(new Runnable() { @Override public void run() { myCallBack.onFailure(request, e); } }); } @Override public void onResponse(Response response) throws IOException { final String json = response.body().string(); if (activity == null) { return; } //直接更新UI activity.runOnUiThread(new Runnable() { @Override public void run() { myCallBack.onResponse(json); } }); } }); } catch (Exception e) { e.printStackTrace(); } } /** * Daemon * -----------------一开始没有发现好的封装对于上传和下载 * 就用的下面的两个方法 后面发现在OKHttp的sample中有相关的例子 然后网上也有人写 就借鉴过来了 * --------------------所以这两个就没用了----------------------------------------------- */ /** * 下载显示进度的方法1 * * @param url */ public static void dowloadProgress(Context context, final String url) { Request request = new Request.Builder().url(url) .build(); new AsyncDownloader(context).execute(request); } private static class AsyncDownloader extends AsyncTask<Request, Long, Boolean> { private Context context; public AsyncDownloader(Context context) { this.context = context; } @Override protected Boolean doInBackground(Request... params) { Call call = mOkHttpClient.newCall(params[0]); try { Response response = call.execute(); if (response.code() == 200) { InputStream inputStream = null; OutputStream output = null; try { inputStream = response.body().byteStream(); File file = new File(context.getCacheDir(), "download.liubo"); output = new FileOutputStream(file); byte[] buff = new byte[1024 * 4]; long downloaded = 0; long target = response.body().contentLength(); publishProgress(0L, target); while (true) { int readed = inputStream.read(buff); if (readed == -1) { break; } //write buff output.write(buff, 0, readed); downloaded += readed; publishProgress(downloaded, target); if (isCancelled()) { return false; } } output.flush(); return downloaded == target; } catch (IOException ignore) { return false; } finally { if (inputStream != null) { inputStream.close(); } if (output != null) { output.close(); } } } else { return false; } } catch (IOException e) { e.printStackTrace(); return false; } } @Override protected void onProgressUpdate(Long... values) { LogUtils.e(String.format("%d / %d", values[0], values[1])); } @Override protected void onPostExecute(Boolean result) { //下载完成后 } } /** * 上传文件方法1 进度显示 */ public static RequestBody createCustomRequestBody(final MediaType contentType, final File file) { return new RequestBody() { @Override public MediaType contentType() { return contentType; } @Override public long contentLength() { return file.length(); } @Override public void writeTo(BufferedSink sink) throws IOException { Source source = null; try { source = Okio.source(file); //sink.writeAll(source); Buffer buf = new Buffer(); Long remaining = contentLength(); for (long readCount; (readCount = source.read(buf, 2048)) != -1; ) { sink.write(buf, readCount); LogUtils.e("source size: " + contentLength() + " remaining bytes: " + (remaining -= readCount)); } } catch (Exception e) { e.printStackTrace(); } } }; } }
这里是一些OKHttp使用中的一些操作
//如果json body这么构建
RequestBody body = RequestBody.create(JSON, json); 如果获取sessionID Map<String, List<String>> map = new HashMap<String, List<String>>(); //获取cookie 然后打印 绑定 try { BaseRequest.Cookies = response.headers().get("Set-Cookie"); Logger.getLogger().e(response.headers().toString()); map = mOkHttpClient.getCookieHandler().get(URI.create(url), response.headers().toMultimap()); for (String key : map.keySet()) { syso(key + " -- " + map.get(key).toString()); if ("Cookie".equals(key)) { sessionId = map.get(key).get(0); } } } catch (IOException e) { e.printStackTrace(); } 在请求的时候带上cookie 在Request构建的时候加上头部就行 .addHeader("cookie", sessionId)
其实很简单 只是新增一个接口 让其可以UI更新
其实大家看到了 上面有两个方法一个是 下载的进度显示和一个上传的进度显示 这是以前使用的 也能达到效果
后面有一天在微博看到相关的封装 对已上传和下载的进度显示 就集成进来项目中
红线部分是对于上传和下载的进度显示的类和接口
这里的话 去看这个吧 我是从这个看到的写的挺好的
http://blog.csdn.net/sbsujjbcy/article/details/48194701
或者这个也行 官方的demo
https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/com/squareup/okhttp/recipes/Progress.java
然后看看在整个项目中的一些设置
有BaseActivity的ondestyoy中的 请求取消
public class BaseActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override protected void onDestroy() { super.onDestroy(); OkHttpUtil.mOkHttpClient.cancel(this); } } //MyApplication的oncreate中的okhttp的cookie的设置 public class MyApplication extends Application { private static Context mInstance; @Override public void onCreate() { super.onCreate(); mInstance = getBaseContext(); //cookie策略 让OkHttp接受所有的cookie CookieManager cookieManager = new CookieManager(); OkHttpUtil.setCookie(cookieManager); } public static Context getContext() { return mInstance; } }
实际运用
/**
* 数据获取Get请求
*/
Request request = new Request.Builder().url("http://www.baidu.com") .tag(this) .build(); OkHttpUtil.postData2Server(this, request, new OkHttpUtil.MyCallBack() { @Override public void onFailure(Request request, IOException e) { } @Override public void onResponse(String json) { showData(json); } });
/**
* 数据上传 Post请求
*/
RequestBody requestBody = new FormEncodingBuilder() .add("action_flag", "user_login") .add("mobile_phone", "18566757335") .add("user_password", "liubo123") .build(); Request request = new Request.Builder() .post(requestBody) .url("登陆接口") .tag(this) .build(); OkHttpUtil.postData2Server(this, request, new OkHttpUtil.MyCallBack() { @Override public void onFailure(Request request, IOException e) { } @Override public void onResponse(String json) { showData(json); } });
/**
* 图片下载
*/
UIProgressResponseListener uiProgressResponseListener = new UIProgressResponseListener() { @Override public void onUIResponseProgress(long bytesRead, long contentLength, boolean done) { LogUtils.e("bytesRead:" + bytesRead); LogUtils.e("contentLength:" + contentLength); LogUtils.e("done:" + done); if (contentLength != -1) { // LogUtils.e( (100 * bytesRead) / contentLength + "% done"); } LogUtils.e("================================"); //ui层回调 tvshow.setText("下载进度 " + ((100 * bytesRead) / contentLength) + "%"); } }; //构造请求 final Request request1 = new Request.Builder() .url("网上资源接口") .build(); //包装Response使其支持进度回调 ProgressHelper.addProgressResponseListener(OkHttpUtil.mOkHttpClient, uiProgressResponseListener) .newCall(request1) .enqueue(new Callback() { @Override public void onFailure(Request request, IOException e) { Log.e("TAG", "error ", e); } @Override public void onResponse(Response response) throws IOException { InputStream inputStream = null; OutputStream output = null; try { inputStream = response.body().byteStream(); file = new File(getCacheDir(), "download.jpg"); output = new FileOutputStream(file); byte[] buff = new byte[1024 * 4]; while (true) { int readed = inputStream.read(buff); if (readed == -1) { break; } //write buff output.write(buff, 0, readed); } output.flush(); } catch (IOException e) { file = null; e.printStackTrace(); } finally { if (inputStream != null) { inputStream.close(); } if (output != null) { output.close(); } } } } );
/**
* 图文上传
*/
private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png"); if (file == null) { ToastUtil.showToast("先下载图片在试着上传吧"); return; } tvshow.setText(""); MultipartBuilder mb = new MultipartBuilder(); mb.type(MultipartBuilder.FORM); mb.addFormDataPart("user_id", "74"); mb.addFormDataPart("user_head", "user_head.jpg", RequestBody.create(MEDIA_TYPE_PNG, file)); RequestBody requestBody = mb.build(); UIProgressRequestListener progressListener = new UIProgressRequestListener() { @Override public void onUIRequestProgress(long bytesWrite, long contentLength, boolean done) { Log.e("TAG", "bytesWrite:" + bytesWrite); Log.e("TAG", "contentLength" + contentLength); Log.e("TAG", (100 * bytesWrite) / contentLength + " % done "); Log.e("TAG", "done:" + done); Log.e("TAG", "================================"); tvshow.setText("上传进度 " + ((100 * bytesWrite) / contentLength) + "%"); } }; Request request = new Request.Builder() .url("上传的接口") .post(new ProgressRequestBody(requestBody, progressListener)) .tag(this) .build(); OkHttpUtil.postData2Server(this, request, new OkHttpUtil.MyCallBack() { @Override public void onFailure(Request request, IOException e) { } @Override public void onResponse(String json) { } });
//数据的显示
private void showData(String json) { tvshow.setText(""); tvshow.setText(json); }
以上就是四个例子的使用方法
关于Json的上传和cookie的使用在OkHttpUtil的注释里面有介绍
因为我写demo的效果都是用的公司的接口 所以上面把接口都给取消 需要的自己把接口加上去才能使用
demo上传到http://download.csdn.net/detail/liubo080852/9094387
有需要的可以下载哈
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories