• OkHttp3的简单使用(一)


    一、导入

    1)gradle方式:

    compile 'com.squareup.okhttp3:okhttp:3.8.0'(okhttp 最新版

    compile 'com.squareup.okio:okio:1.13.0'(okio最新版

    2)jar包导入

    okhttp-3.3.0.jar
    okio-1.8.0.jar

    3)权限

    <!--网络访问权限-->
    <uses-permission android:name="android.permission.INTERNET"/>
    <!-- 外置存储存取权限 -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    二、使用

    同步:execute()       异步:enqueue(new Callback()...)

    一)get请求

    String url="http://www,baidu.com/";
    OkHttpClient client=new OkHttpClient();
    Request request=new Request.Builder()
    .url(url)
    .build();
    Call call=client.newCall(request);
    
    //同步
    try {
    Response response=call.execute();
    if(response.isSuccessful()){
    Log.e(TAG, "onCreate: "+response.body().string() );
    }
    } catch (IOException e) {
    e.printStackTrace();
    }
    
    //异步
    call.enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
    //失败
    Log.e(TAG, "onFailure: 失败:"+e.getMessage() );
    }
    
    @Override
    public void onResponse(Call call, Response response) throws IOException {
    //成功
    Log.e(TAG, "onResponse: "+response.body().string() );
    }
    });

    二)POST请求JSON格式

    String url="http://www,baidu.com/";
    OkHttpClient client=new OkHttpClient();
    
    MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    RequestBody body = RequestBody.create(JSON, "你的json");
    
    Request request=new Request.Builder()
    .url(url)
    .post(requestBody)
    .build();
    
    Call call=client.newCall(request);
    
    //同步
    try {
    Response response=call.execute();
    if(response.isSuccessful()){
    Log.e(TAG, "onCreate: "+response.body().string() );
    }
    } catch (IOException e) {
    e.printStackTrace();
    }
    
    //异步
    call.enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
    //失败
    Log.e(TAG, "onFailure: 失败:"+e.getMessage() );
    }
    
    @Override
    public void onResponse(Call call, Response response) throws IOException {
    //成功
    Log.e(TAG, "onResponse: "+response.body().string() );
    }
    });

    三)POST请求表单格式

    post请求创建request和get是一样的,只是post请求需要提交一个表单,就是RequestBody。表单的格式有好多种,普通的表单是:
    RequestBody body = new FormBody.Builder()
    .add("键", "值")
    .add("键", "值")
    ...
    .build();

    普通表单:
    RequestBody body = new FormBody.Builder()
    .add("键", "值")
    .add("键", "值")
    ...
    .build();
    FormBody继承了RequestBody,它已经指定了数据类型为application/x-www-form-urlencoded
    private static final MediaType CONTENT_TYPE = MediaType.parse("application/x-www-form-urlencoded");

    四)上传文件

    //创建 MediaType 设置上传文件类型
    MediaType MEDIATYPE = MediaType.parse("text/plain; charset=utf-8");
    //获取请求体
    RequestBody requestBody = RequestBody.create(MEDIATYPE, file);
    //创建请求
    Request request = new Request.Builder().url("http://www.baidu.com")
    .post(requestBody)
    .build();

    五)上传Multipart文件

    //定义上传文件类型
    private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");

    RequestBody requestBody = new MultipartBody.Builder()
    .setType(MultipartBody.FORM)//数据格式 带有文件
    .addFormDataPart("title", "wangshu") //键值对参数
    .addFormDataPart("image", "wangshu.jpg",
    RequestBody.create(MEDIA_TYPE_PNG, new File("/sdcard/wangshu.jpg"))) //要上传的文件
    .build();



    RequestBody的数据格式都要指定Content-Type,常见的有三种:
    application/x-www-form-urlencoded 数据是个普通表单
    multipart/form-data 数据里有文件
    application/json 数据是个json

    MediaType的创建:
    MediaType MEDIATYPE = MediaType.parse("text/plain; charset=utf-8");

    如果表单是个json:
    MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    RequestBody body = RequestBody.create(JSON, "你的json");

    如果数据中包含文件:
    RequestBody requestBody = new MultipartBody.Builder()
    .setType(MultipartBody.FORM)
    .addFormDataPart("键","值”)
    .addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse("image/png"), file))
    .build();
    另外如果你上传一个文件不是一张图片,但是MediaType.parse("image/png")里的"image/png"不知道该填什么,可以参考(http://www.w3school.com.cn/media/media_mimeref.asp)。


    常见的文件类型:
    参数 说明
    text/html HTML格式
    text/plain 纯文本格式
    text/xml XML格式
    image/gif gif图片格式
    image/jpeg jpg图片格式
    image/png png图片格式
    application/xhtml+xml XHTML格式
    application/xml XML数据格式
    application/atom+xml Atom XML聚合格式
    application/json JSON数据格式
    application/pdf pdf格式
    application/msword Word文档格式
    application/octet-stream 二进制流数据

    六)设置超时时间和缓存

    OkHttpClient.Builder builder = new OkHttpClient.Builder()
    .connectTimeout(15, TimeUnit.SECONDS) //设置连接超时
    .writeTimeout(20, TimeUnit.SECONDS) //写入超时
    .readTimeout(20, TimeUnit.SECONDS) //读取超时
    .cache(new Cache(sdcache.getAbsoluteFile(), cacheSize));
    OkHttpClient mOkHttpClient=builder.build();

    七)添加请求头

    okhttp3添加请求头,需要在Request.Builder()使用.header(String key,String value)或者.addHeader(String key,String value);
    使用.header(String key,String value),如果key已经存在,将会移除该key对应的value,然后将新value添加进来,即替换掉原来的value;
    使用.addHeader(String key,String value),即使当前的可以已经存在值了,只会添加新value的值,并不会移除/替换原来的值。
    还有.headers(Headers headers)添加请求头集合

    Request request = new Request.Builder()
    .url("https://api.github.com/repos/square/okhttp/issues")
    .header("User-Agent", "OkHttp Headers.java")
    .addHeader("Accept", "application/json; q=0.5")
    .addHeader("Accept", "application/vnd.github.v3+json")
    .build();

    /**
    * 设置请求头
    * @param headersParams
    * @return
    */
    private Headers SetHeaders(Map<String, String> headersParams){
    Headers headers=null;
    okhttp3.Headers.Builder headersbuilder=new okhttp3.Headers.Builder();

    if(headersParams != null)
    {
    Iterator<String> iterator = headersParams.keySet().iterator();
    String key = "";
    while (iterator.hasNext()) {
    key = iterator.next().toString();
    headersbuilder.add(key, headersParams.get(key));
    Log.d("get http", "get_headers==="+key+"===="+headersParams.get(key));
    }
    }
    headers=headersbuilder.build();

    return headers;
    }

    八)取消请求

    使用call.cancel()可以立即停止掉一个正在准备的同步/异步请求call。如果一个线程正在写请求或者读响应,将会引发IOException。
    当用户离开一个应用时或者跳到其他界面时,使用Call.cancel()可以节约网络资源,另外不管同步还是异步的call都可以取消。
    也可以通过tags来同时取消多个请求。当你构建一请求时,使用RequestBuilder.tag(tag)来分配一个标签。
    之后你就可以用OkHttpClient.cancel(tag)来取消所有带有这个tag的call。

    九)自动管理Cookie

    Request经常都要携带Cookie,上面说过request创建时可以通过header设置参数,Cookie也是参数之一。就像下面这样:
    Request request = new Request.Builder()
    .url(url)
    .header("Cookie", "xxx")
    .build();

    OkHttp可以不用我们管理Cookie,自动携带,保存和更新Cookie。
    方法是在创建OkHttpClient设置管理Cookie的CookieJar: 

    private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();
    OkHttpClient okHttpClient = new OkHttpClient.Builder()
    .cookieJar(new CookieJar() {
    @Override
    public void saveFromResponse(HttpUrl httpUrl, List<Cookie> list) {
    cookieStore.put(httpUrl.host(), list);
    }

    @Override
    public List<Cookie> loadForRequest(HttpUrl httpUrl) {
    List<Cookie> cookies = cookieStore.get(httpUrl.host());
    return cookies != null ? cookies : new ArrayList<Cookie>();
    }
    })
    .build();


    这样以后发送Request都不用管Cookie这个参数也不用去response获取新Cookie什么的了。还能通过cookieStore获取当前保存的Cookie。
    最后,new OkHttpClient()只是一种快速创建OkHttpClient的方式,更标准的是使用OkHttpClient.Builder()。后者可以设置一堆参数,例如超时时间什么的。

     注意事项

    Android 4.0之后要求网络请求必须在工作线程中运行,不允许在主线程中运行。因此如果使用OkHttp3的同步方法,需要新起工作线程进行调用。
    一般情况下我们希望获得Response返回的字符串,可以通过response.body().string()获取;
    如果希望获得返回的二进制字节数组,则调用response.body().bytes();
    如果想获取到返回的InputStream,则调用response.body().byteStream()。
    异步请求enqueue的回调是子线程,非主线程,所以是不能直接操作UI界面的。
    响应体的string()方法适用于获取小数据信息,如果返回的数据太大(超过1MB),
    建议使用stream()获取返回的数据,因为string()方法会将整个文档加载到内存中。

    参考:

    http://blog.csdn.net/lmj623565791/article/details/47911083
    http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0106/2275.html
    http://www.2cto.com/kf/201604/501946.html
    http://blog.csdn.net/feixiang_gao/article/details/53760705
    http://blog.csdn.net/chinaboyliusir/article/details/51261929
    http://blog.csdn.net/wwwkp1236/article/details/51374320
    https://github.com/MrZhousf/OkHttp3

  • 相关阅读:
    使用 udev 高效、动态地管理 Linux 设备文件
    【技术贴】visual stdio 2005下载地址,vs2005下载地址 vs2005正版破解 v
    【转】无法登陆SQL server 服务器的解决办法
    【技术贴】visual stdio 2005下载地址,vs2005下载地址 vs2005正版破解 v
    【技术贴】远程桌面连接 时“由于帐户限制 您无法登陆”的解决办法
    【转】桌面快捷方式打不开的解决办法
    【技术贴】从51下载的网站代码asp源码怎么运行?怎么打开?
    【转】Visual Studio 2005不能调试的错误
    【技术贴】asms文件,安装windows xp原版时,需要“asms”文件,H:\I386\asm
    【技术贴】asms文件,安装windows xp原版时,需要“asms”文件,H:\I386\asm
  • 原文地址:https://www.cnblogs.com/wangjiaghe/p/6931130.html
Copyright © 2020-2023  润新知