okhttp 是 Android6.0 推出的网络框架。这篇文章主要介绍了 Android-Okhttp 的使用解析, 具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
Android 是一种基于 Linux 的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由 Google 公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用 "安卓" 或 "安致"。
okhttp 是 Android6.0 推出的网络框架。由于谷歌在 Android6.0 的之后,将 HttpClient 相关属性取消掉,导致 Volley 框架不能正常使用。所以才有了今天的 Okhttp。
Okhttp 进行网络访问通常有两种方式,一种是 get 请求,还有一种叫做 post 请求。
1、OKhttp 的 get 请求
通常,我们使用 get 方式来请求一个网站,是依靠 url 地址的。Okhttp 使用 get 方式来请求网站通常有如下的步骤:
A、创建 OkhttpClient 的变量,这个变量相当于是一个全局的执行者。主要的网络操作是依靠它来进行的。
B、创建一个 builder 对象。
C、利用 builder 对象创建一个 Request 对象。
D、使用全局执行者来创建一个 Call 对象。
E、通过 Call 对象来进行网络连接。
- public void doGet(View view)
- {
- Request.Builder builder = new Request.Builder();
- Request request = builder.get().url(urlString + "userName=pby&userPassword=123").build();
- Call newCall = mOkHttpClient.newCall(request);
- //newCall.execute()
- newCall.enqueue(new Callback() {
- @Override
- public void onFailure(Request request, IOException e) {
- L.e("失败了");
- }
- @Override
- public void onResponse(Response response) throws IOException {
- String string = response.body().string();
- L.e(string);
- }
- });
- }
2、Okhttp 的 Post 请求
Post 请求与 get 请求有些不一样。get 请求主要的功能是从服务器上获取数据,而 Post 请求则是向服务器提交数据。
- public void doPost(View view)
- {
- FormEncodingBuilder requestBodyBuilder = new FormEncodingBuilder();
- RequestBody requestBody = requestBodyBuilder.add("userName", "pby").add("userPassword", "123").build();
- Request.Builder builder = new Request.Builder();
- Request request = builder.url(urlString).post(requestBody).build();
- Call newCall = mOkHttpClient.newCall(request);
- executeCall(newCall);
- }
3、服务器端接收客户端传过来的字符串
客户端的代码:
- public void doPostString(View view)
- {
- RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain;charset = utf-8"), "{name = pby, password = 1234}");
- Request.Builder builder = new Request.Builder();
- Request request = builder.url(urlString + "doPostString").post(requestBody).build();
- Call newCall = mOkHttpClient.newCall(request);
- executeCall(newCall);
- }
服务器端的代码:
- public String doPostString() throws IOException
- {
- HttpServletRequest request = ServletActionContext.getRequest();
- ServletInputStream inputStream = request.getInputStream();
- StringBuilder sb = new StringBuilder();
- int len = 0;
- byte []buff = new byte[1024];
- while((len = inputStream.read(buff)) != -1)
- {
- sb.append(new String(buff, 0, len));
- }
- System.out.println(sb.toString());
- return null;
- }
服务器端如果要接收客户端的数据,则需要接收 request;如果服务器端想要给客户端传数据,则需要通过 response 来传递。
4、使用 post 方式进行文件的传输
客户端的代码
- public void doPost(View view)
- {
- FormEncodingBuilder requestBodyBuilder = new FormEncodingBuilder();
- RequestBody requestBody = requestBodyBuilder.add("userName", "pby").add("userPassword", "123").build();
- Request.Builder builder = new Request.Builder();
- Request request = builder.url(urlString + "login").post(requestBody).build();
- Call newCall = mOkHttpClient.newCall(request);
- executeCall(newCall);
- }
关于选择文件的代码 -- 抄袭网络上的代码,并不是自己写的
- private void showFileChooser() {
- Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
- intent.setType("*/*");
- intent.addCategory(Intent.CATEGORY_OPENABLE);
- try {
- startActivityForResult( Intent.createChooser(intent, "Select a File to Upload"), 1);
- } catch (android.content.ActivityNotFoundException ex) {
- Toast.makeText(this, "Please install a File Manager.", Toast.LENGTH_SHORT).show();
- }
- }
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- switch (requestCode) {
- case 1:
- if (resultCode == RESULT_OK) {
- // Get the Uri of the selected file
- Uri uri = data.getData();
- String path = FileUtils.getPath(this, uri);
- if(path != null)
- {
- postFile(path);
- }
- }
- break;
- }
- super.onActivityResult(requestCode, resultCode, data);
- }
在进行这个的操作的时候,一定要记住增加读和写的权限,否则会上传失败的。
服务器端的代码
- public String doPostFile() throws IOException
- {
- HttpServletRequest request = ServletActionContext.getRequest();
- ServletInputStream inputStream = request.getInputStream();
- String dir = ServletActionContext.getServletContext().getRealPath("files");
- File file = new File(dir, "abc.jpg");
- FileOutputStream fos = new FileOutputStream(file);
- int len = 0;
- byte [] buff = new byte[1024];
- while((len = inputStream.read(buff)) != -1)
- {
- fos.write(buff, 0, len);
- }
- fos.flush();
- fos.close();
- return null;
- }
上面显示的 files 文件,在 Tomcat 的 webapps 下的工程名名文件下的 fies 文件夹(才开始是没有这个文件夹的,需要手动自己创建)。
5. 使用 Post 方式来上传文件
客户端代码:
- private void upLoadFile(String path)
- {
- File file = new File(path);
- if(!file.exists())
- {
- return ;
- }
- MultipartBuilder multipartBuilder = new MultipartBuilder();
- RequestBody requestBody = multipartBuilder.type(MultipartBuilder.FORM)
- .addFormDataPart("userName", "pby")
- .addFormDataPart("userPassword", "123")
- .addFormDataPart("mFile", file.getName(), RequestBody.create(MediaType.parse("application/octet-stream"), file)).build();
- // CountingRequestBody countingRequestBody = new CountingRequestBody(requestBody, new CountingRequestBody.MyListener() {
- // @Override
- // public void onRequestProgress(int byteWriteCount, int TotalCount) {
- // L.e(byteWriteCount + " / " + TotalCount);
- // }
- // });
- Request.Builder builder = new Request.Builder();
- //Request request = builder.url(urlString + "doUpLoadFile").post(countingRequestBody).build();
- Request request = builder.url(urlString + "doUpLoadFile").post(requestBody).build();
- Call newCall = mOkHttpClient.newCall(request);
- executeCall(newCall);
- }
服务器端的代码:
- public String doUpLoadFile()
- {
- if(mFile == null)
- {
- System.out.println(mFileFileName+" is null..");
- return null;
- }
- String dir = ServletActionContext.getServletContext().getRealPath("files");
- File file = new File(dir, mFileFileName);
- try {
- FileUtils.copyFile(mFile, file);
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return null;
- }
在上传文件的时候,有一个小细节都注意到:就是 Tomcat 服务器只允许上传 2m 以下的文件。要想上传大文件,就必须在 struct 文件中加一句:<constant name="struts.multipart.maxSize"value="1024000000"/> 数字表示自定义大小的限制。
6. 上传文件时,进度的显示问题
在写代码的时候我们知道,我们不能直接获得上传文件的进度。因为这些数据都是封装在 RequestBody 里面的,要想使用只有通过回调接口来实现。
- package com.example.android_okhttp;
- import com.squareup.okhttp.MediaType;
- import com.squareup.okhttp.RequestBody;
- import java.io.IOException;
- import okio.Buffer;
- import okio.BufferedSink;
- import okio.ForwardingSink;
- import okio.Okio;
- import okio.Sink;
- /**
- * Created by 前世诀别的一纸书 on 2017/3/5.
- */
- public class CountingRequestBody extends RequestBody {
- private RequestBody delegate = null;
- private MyListener mListener= null;
- private CountingSink mCountSink = null;
- public interface MyListener
- {
- void onRequestProgress(int byteWriteCount, int TotalCount);
- }
- public CountingRequestBody(RequestBody requestBody, MyListener listener)
- {
- delegate = requestBody;
- mListener = listener;
- }
- @Override
- public MediaType contentType() {
- return delegate.contentType();
- }
- @Override
- public void writeTo(BufferedSink sink) throws IOException {
- mCountSink = new CountingSink(sink);
- BufferedSink bs = Okio.buffer(mCountSink);
- delegate.writeTo(bs);
- bs.flush();
- }
- private class CountingSink extends ForwardingSink{
- private int byteWriteCount = 0;
- public CountingSink(Sink delegate) {
- super(delegate);
- }
- @Override
- public void write(Buffer source, long byteCount) throws IOException {
- super.write(source, byteCount);
- byteWriteCount += byteCount;
- mListener.onRequestProgress(byteWriteCount, (int) contentLength());
- }
- }
- @Override
- public long contentLength() throws IOException {
- return delegate.contentLength();
- }
- }
- MultipartBuilder multipartBuilder = new MultipartBuilder();
- RequestBody requestBody = multipartBuilder.type(MultipartBuilder.FORM)
- .addFormDataPart("userName", "pby")
- .addFormDataPart("userPassword", "123")
- .addFormDataPart("mFile", file.getName(), RequestBody.create(MediaType.parse("application/octet-stream"), file)).build();
- CountingRequestBody countingRequestBody = new CountingRequestBody(requestBody, new CountingRequestBody.MyListener() {
- @Override
- public void onRequestProgress(int byteWriteCount, int TotalCount) {
- L.e(byteWriteCount + " / " + TotalCount);
- }
- });
- Request.Builder builder = new Request.Builder();
- Request request = builder.url(urlString + "doUpLoadFile").post(countingRequestBody).build();
- //Request request = builder.url(urlString + "doUpLoadFile").post(requestBody).build();
- Call newCall = mOkHttpClient.newCall(request);
来源: http://www.phperz.com/article/17/0316/326170.html