欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android-Okhttp的使用解析

程序员文章站 2023-11-27 08:36:04
okhttp是android6.0推出的网络框架。由于谷歌在android6.0的之后,将httpclient相关属性取消掉,导致volley框架不能正常使用。所以才有了今...

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

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