Android-Okhttp的使用解析

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);

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android使用okHttp(get方式)登录

    本文实例为大家分享了Android使用get方式登录的相关代码,供大家参考,具体内容如下 工具类 package com.liunan.okhttpdemo3post.Utils; import java.io.IOException; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response;

  • 使用Android的OkHttp包实现基于HTTP协议的文件上传下载

    OkHttp的HTTP连接基础 虽然在使用 OkHttp 发送 HTTP 请求时只需要提供 URL 即可,OkHttp 在实现中需要综合考虑 3 种不同的要素来确定与 HTTP 服务器之间实际建立的 HTTP 连接.这样做的目的是为了达到最佳的性能. 首先第一个考虑的要素是 URL 本身.URL 给出了要访问的资源的路径.比如 URL http://www.baidu.com 所对应的是百度首页的 HTTP 文档.在 URL 中比较重要的部分是访问时使用的模式,即 HTTP 还是 HTTPS.这

  • Android M(6.x)使用OkHttp包解析和发送JSON请求的教程

    关于Android 6.0 Android老版本网络请求: 1,HttpUrlConnection 2,Apache Http Client Android6.0版本网络请求: 1,HttpUrlConnection 2,OkHttp Android6.0版本废弃了老的网络请求,那么它的优势是什么呢? 1,支持SPDY,共享同一个Socket来处理同一个服务器的所有请求 2,如果SPDY不可用,则通过连接池来减少请求延时 3,无缝的支持GZIP来减少数据流量 4,缓存响应数据来减少重复的网络请求

  • Android的HTTP扩展包OkHttp中的缓存功能使用方法解析

    OkHttp 可以对 HTTP 响应的内容在磁盘上进行缓存.在进行 HTTP 请求时,如果该请求的响应已经被缓存而且没有过期,OkHttp 会直接使用缓存中的响应内容,而不需要真正的发出 HTTP 请求到远程服务器.在创建缓存时需要指定一个磁盘目录和缓存的大小.在代码清单 8 中,创建出 Cache 对象之后,通过 OkHttpClient 的 setCache 进行设置.通过 Response 对象的 cacheResponse 和 networkResponse 方法可以得到缓存的响应和从实

  • 详解Android使用OKHttp3实现下载(断点续传、显示进度)

    OKHttp3是如今非常流行的Android网络请求框架,那么如何利用Android实现断点续传呢,今天写了个Demo尝试了一下,感觉还是有点意思 准备阶段 我们会用到OKHttp3来做网络请求,使用RxJava来实现线程的切换,并且开启Java8来启用Lambda表达式,毕竟RxJava实现线程切换非常方便,而且数据流的形式也非常舒服,同时Lambda和RxJava配合食用味道更佳 打开我们的app Module下的build.gradle,代码如下 apply plugin: 'com.an

  • Android OkHttp的简单使用和封装详解

    Android OkHttp的简单使用和封装详解 1,昨天把okHttp仔细的看了一下,以前都是调用同事封装好了的网络框架,直接使用很容易,但自己封装却不是那么简单,还好,今天就来自我救赎一把,就和大家写写从最基础的OKHttp的简单get.post的使用,再到它的封装. 2,OkHttp的简单使用 首先我们创建一个工程,并在布局文件中添加三个控件,TextView(用于展示获取到json后的信息).Button(点击开始请求网络).ProgressBar(网络加载提示框) ①简单的异步Get请

  • Android使用okHttp(get方式)下载图片

    一.首先下载Jar包 https://github.com/square/okhttp 如果使用android studio只需要加入依赖compile 'com.squareup.okhttp3:okhttp:3.2.0' 二.下载一张图片并显示 使用的是hanlder的方式 package com.liunan.okhttpdemo2; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import

  • Android的OkHttp包中的HTTP拦截器Interceptor用法示例

    OkHttp(GitHub:https://github.com/square/okhttp) 的 Interceptor 就如同名称「拦截器」一样,拦截你的 Request 做一些你想做的事情再送出去.例如: 1.自动加上使用者目前使用的语言送出去取得对应语言的回传内容. 2.将 Request 计算出这个 Request 的 sigunature 再附加上送出去. 在 okHttp 中分成 Application Interceptor 和 Network Interceptor 两种. A

  • 详解Android中使用OkHttp发送HTTP的post请求的方法

    HTTP POST 和 PUT 请求可以包含要提交的内容.只需要在创建 Request 对象时,通过 post 和 put 方法来指定要提交的内容即可. HTTP POST 请求的基本示例: public class PostString { public static void main(String[] args) throws IOException { OkHttpClient client = new OkHttpClient(); MediaType MEDIA_TYPE_TEXT

  • Android的OkHttp包处理用户认证的代码实例分享

    OkHttp 提供了对用户认证的支持.当 HTTP 响应的状态代码是 401 时,OkHttp 会从设置的 Authenticator 对象中获取到新的 Request 对象并再次尝试发出请求.Authenticator 接口中的 authenticate 方法用来提供进行认证的 Request 对象,authenticateProxy 方法用来提供对代理服务器进行认证的 Request 对象. 用户认证的示例: OkHttpClient client = new OkHttpClient();

  • 使用OkHttp包在Android中进行HTTP头处理的教程

    HTTP 头处理 HTTP 头是 HTTP 请求和响应中的重要组成部分.在创建 HTTP 请求时需要设置一些 HTTP 头.在得到 HTTP 的响应之后,也会需要对其中包含的 HTTP 头进行解析.从代码的角度来说,HTTP 头的数据结构是 Map<String, List<String>>类型.也就是说,对于每个 HTTP 头,可能有多个值.但是大部分 HTTP 头都只有一个值,只有少部分 HTTP 头允许多个值.OkHttp 采用了简单的方式来区分这两种类型,使得对 HTTP

随机推荐