看了你就会的OkHttp介绍

1:OKHttp介绍

1.1简介

OKHttp是一款高效的HTTP客户端,支持连接同一地址的链接共享同一个socket,通过连接池来减小响应延迟,还有透明的GZIP压缩,请求缓存等优势,其核心主要有路由连接协议拦截器代理安全性认证连接池以及网络适配,拦截器主要是++指添加,移除或者转换请求或者回应的头部信息++

这个库也是square开源的一个网络请求库(okhttp内部依赖okio)。现在已被Google使用在Android源码上了,可见其强大。

关于网络请求库,现在应该还有很多人在使用android-async-http。他内部使用的是HttpClient,但是Google在6.0版本里面删除了HttpClient相关API,可见这个库现在有点过时了。

OkHttp最低支持Android2.3,最低支持java1.7.

对于square这个公司还有许多优秀的开源项目,例如Retrofitpicasso等,这些随后都会详细的说明。

1.2下载地址

https://github.com/square/okhttp

1.3OKHttp主要功能

  1. 联网请求文本数据
  2. 大文件下载
  3. 大文件上传
  4. 请求图片

2:原生OKHttp的Get和Post请求小案例

2.1使用前配置

2.1.1 参照网址:

http://square.github.io/okhttp/ 里面有对okhttp使用的描述,下面是里面主要的get和set方法。

2.1.2 get a rul:

OkHttpClient client = new OkHttpClient();

String run(String url) throws IOException {
  Request request = new Request.Builder()
      .url(url)
      .build();

  Response response = client.newCall(request).execute();
  return response.body().string();
}

2.1.3 post to a server

public static final MediaType JSON
    = MediaType.parse("application/json; charset=utf-8");

OkHttpClient client = new OkHttpClient();

String post(String url, String json) throws IOException {
  RequestBody body = RequestBody.create(JSON, json);
  Request request = new Request.Builder()
      .url(url)
      .post(body)
      .build();
  Response response = client.newCall(request).execute();
  return response.body().string();
}

2.1.4 最新的jar包

项目中要想使用OkHttp,有两种方法。

  1. 导入OkHttp的jar包,因其内部依赖Okio,所以还需要导入okio的jar包,
  2. 可以直接在项目中添加gradle配置,compile ‘com.squareup.okhttp3:okhttp:(insert latest version)’
  3. 小编写此文章时候最新的OkHttp版本是okhttp-3.5.0,最新的okiio版本是okio-1.11.0。
  4. 将下载好的两个jar包导入到自己的项目中使用

2.2Get请求

2.2.1布局

在项目布局activity_main.xml中添加发送get请求和post请求的按钮,并添加显示请求结果的textview,这里省略布局。。。最重要的别往了添加网络请求权限。

<uses-permission android:name="android.permission.INTERNET"/>

2.2.2主程序

在MainActivity.java中添加相应按钮的点击事件,在点击get按钮执行get请求,将请求成功的数据显示在textview上。

从2.1.2中可以看到,首先需要new一个OkHttpClient供访问网络使用。

OkHttpClient client = new OkHttpClient();

get请求核心方法

/**
     * get请求,要在子线程运行
     *
     * @param url 请求的地址
     * @return
     * @throws IOException
     */
    String okGet(String url) throws IOException {
        Request request = new Request.Builder()
                .url(url)
                .build();

        Response response = client.newCall(request).execute();
        return response.body().string();
    }

点击get请求按钮调用下面方法来得到请求成功返回的json数据,因为网络的访问是一个耗时的操作,这个需要单独开一个线程,最后通过Handle机制来加载请求成功的结果。

private void getDataFromGet() {
        new Thread() {
            @Override
            public void run() {
                super.run();
                try {
                    String result = okGet("http://api.m.mtime.cn/PageSubArea/TrailerList.api");
                    Message msg = new Message();
                    msg.what = GET;
                    msg.obj = result;
                    mHandler.sendMessage(msg);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();

    }

Handler得到数据加载显示

Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case GET:
                    tv_result.setText(msg.obj.toString());
                    break;
            }
        }
    };

get请求结果

2.3Post请求

从2.1.3中我们可以看到post请求的方法,拷贝上面的代码到MainActivity.java中,去掉再get请求中已经添加的OkHttpClient client = new OkHttpClient(),然后像get方法一样,在新的线程中进行请求调用,结果同样通过Handle消息机制发出并在textview上加载服务器返回的json数据。

post请求核心方法

/**
     * post请求,要在子线程运行
     *
     * @param url  请求链接
     * @param json 参数
     * @return
     * @throws IOException
     */
    String okPost(String url, String json) throws IOException {
        MediaType JSON = MediaType.parse("application/json; charset=utf-8");
        RequestBody body = RequestBody.create(JSON, json);
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        Response response = client.newCall(request).execute();
        return response.body().string();
    }

post按钮点击调用下面方法,okPost()方法的第二个参数是请求参数,这里没有参数,就传入空字符串,最后和get请求一样,利用Handle加载数据。

private void getDataFromPost() {
        new Thread() {
            @Override
            public void run() {
                super.run();
                try {
                    String result = okPost("http://api.m.mtime.cn/PageSubArea/TrailerList.api", "");
                    Message msg = new Message();
                    msg.what = POST;
                    msg.obj = result;
                    mHandler.sendMessage(msg);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();

    }

post请求结果

3第三方封装好的OKHttp库(1)————okhttputils

3.1okhttp-utils简介

okhttputils是鸿洋大神基于OkHttp3.3.1的一个封装,最新的版本是3.5.0,主要包含有:

- 一般的get请求

- 一般的post请求

- 基于Http的文件上传

- 文件下载

- 加载图片

- 支持请求回调,直接返回对象、对象集合

- 支持session的保持

可以参考他这篇文章的博客:http://blog.csdn.net/lmj623565791/article/details/47911083

3.2下载导入自己的工程

okhttputils的Github地址:https://github.com/hongyangAndroid/okhttputils

将下载好的文件解压后,以库工程的形式导入到 项目中,但会有一些错误。

3.3解决报错

3.3.1在自己项目的gradle文件中增加如下代码

allprojects {
    repositories {
        jcenter()
        maven { url "https://www.jitpack.io" }
    }
}

3.3.2把okhttp-utils集成到案例中

关联库

compile project(‘:okhttputils‘)

解决报错

dependencies {
    compile fileTree(dir: ‘libs‘, include: [‘*.jar‘])
    testCompile ‘junit:junit:4.12‘
    compile ‘com.android.support:appcompat-v7:23.3.0‘
//    compile files(‘libs/okhttp-3.4.1.jar‘)
//    compile files(‘libs/okio-1.9.0.jar‘)
    compile project(‘:okhttputils‘)
}

重新运行程序,点击get或者post请求,哇哦,奔溃了,,百思不得其解,一怒之下,删掉了Jar包,然后运行、点击按钮得到了json数据,这一点需要特别注意。

3.4使用okhttp-utils请求文本

在MainActivity.java中使用原生的OkHttp的get和post方法,这里新建一个HYOkhttpActivity.java类,专门用来使用okhttputils中的方法

,布局都很简单,不多说明。

get请求

/**
     * 使用okhttputils的get请求
     * @param view
     */
    public void getDataByOkhttputils(View view) {
        String url = "http://www.zhiyun-tech.com/App/Rider-M/changelog-zh.txt";
        url = "http://api.m.mtime.cn/PageSubArea/TrailerList.api";
        OkHttpUtils
                .get()
                .url(url)
                .id(100)
                .build()
                .execute(new MyStringCallback());
    }

MyStringCallback类是一个回调类,继承自okhttputils中的StringCallback类,在这里面处理请求网络前、请求网络后、请求错误、请求成功以及进度的回调,代码如下:

 public class MyStringCallback extends StringCallback {
        @Override
        public void onBefore(Request request, int id) {
            setTitle("loading...");
        }

        @Override
        public void onAfter(int id) {
            setTitle("Sample-okHttp");
        }

        @Override
        public void onError(Call call, Exception e, int id) {
            e.printStackTrace();
            tv_result.setText("onError:" + e.getMessage());
        }

        @Override
        public void onResponse(String response, int id) {
            Log.e(TAG, "onResponse:complete");
            tv_result.setText("onResponse:" + response);

            switch (id) {
                case 100:
                    Toast.makeText(HYOkhttpActivity.this, "http", Toast.LENGTH_SHORT).show();
                    break;
                case 101:
                    Toast.makeText(HYOkhttpActivity.this, "https", Toast.LENGTH_SHORT).show();
                    break;
            }
        }

        @Override
        public void inProgress(float progress, long total, int id) {
            Log.e(TAG, "inProgress:" + progress);
//            mProgressBar.setProgress((int) (100 * progress));
        }
    }

运行结果就是在tv_result上加上请求成功的json数据,就不写了。

post请求

post请求和get请求一样,只需要把get请求中的get方法换成post方法即可,只是这里。

/**
     * 使用okhttputils的post请求
     * @param view
     */
    public void postDataByOkhttputils(View view) {
        String url = "http://www.zhiyun-tech.com/App/Rider-M/changelog-zh.txt";
        url = "http://api.m.mtime.cn/PageSubArea/TrailerList.api";
        OkHttpUtils
                .post()
                .url(url)
                .id(100)
                .build()
                .execute(new MyStringCallback());
    }

运行结果和get请求一样。

3.5使用okhttp-utils下载文件

下载文件主要方法,这里下载一个视频

 public void downloadFile(View view)
    {
        String url = "http://vfx.mtime.cn/Video/2016/12/14/mp4/161214234616222245.mp4";
        OkHttpUtils//
                .get()//
                .url(url)//
                .build()//
                //下载的文件路径   和  名称
                .execute(new FileCallBack(Environment.getExternalStorageDirectory().getAbsolutePath(), "okhttp-utils-test.mp4")//
                {

                    @Override
                    public void onBefore(Request request, int id)
                    {
                    }

                    @Override
                    public void inProgress(float progress, long total, int id)
                    {
                        mProgressBar.setProgress((int) (100 * progress));
                        //打印进度信息
                        Log.e(TAG, "inProgress :" + (int) (100 * progress));
                    }

                    @Override
                    public void onError(Call call, Exception e, int id)
                    {
                        //打印出错的信息
                        Log.e(TAG, "onError :" + e.getMessage());
                    }

                    @Override
                    public void onResponse(File file, int id)
                    {
                        //打印下载文件的路径
                        Log.e(TAG, "onResponse :" + file.getAbsolutePath());
                    }
                });
    }

进度回调的打印信息如下,下载的文件就在手机根目录,视频是可以播放的。

E/HYOkhttpActivity: inProgress :0  

省略。。。。

E/HYOkhttpActivity: inProgress :100

E/HYOkhttpActivity: onResponse :/storage/emulated/0/okhttp-utils-test.mp4

3.6使用okhttp-utils上传文件

上传文件的时候调用下面的方法,其中mBaseUrl是自己搭建的本地服务器的地址,

/**
     * 使用okhttputils 上传多个或者单个文件
     *
     * @param view
     */
    public void multiFileUpload(View view) {
        String mBaseUrl = "http://192.168.31.11:8080/FileUpload/FileUploadServlet";
        File file = new File(Environment.getExternalStorageDirectory(), "code.jpg");
        File file2 = new File(Environment.getExternalStorageDirectory(), "123.txt");
        if (!file.exists() || !file2.exists()) {
            Toast.makeText(HYOkhttpActivity.this, "文件不存在,请修改文件路径", Toast.LENGTH_SHORT).show();
            return;
        }
        Map<String, String> params = new HashMap<>();
        params.put("username", "bruceChang");
        params.put("password", "123");

        String url = mBaseUrl;
        OkHttpUtils.post()//
                .addFile("mFile", "server_code.jpg", file)//
//                .addFile("mFile", "123.txt", file2)//
                .url(url)
                .params(params)//
                .build()//
                .execute(new MyStringCallback());
    }

结果:

3.7使用okhttp-utils请求单张图片

调用方法,将请求的图片加载到iv_http这个ImageView上,从运行的结果来看,在请求单张图片的时候还是不错的,但在加载列表图片的时候就有问题了。

 /**
     * 使用okhttputils 请求单张图片
     *
     * @param view
     */
    public void getImage(View view) {
        tv_result.setText("");
        String url = "http://images.csdn.net/20150817/1.jpg";
        OkHttpUtils
                .get()//
                .url(url)//
                .tag(this)//
                .build()//
                .connTimeOut(20000)
                .readTimeOut(20000)
                .writeTimeOut(20000)
                .execute(new BitmapCallback() {
                    @Override
                    public void onError(Call call, Exception e, int id) {
                        tv_result.setText("onError:" + e.getMessage());
                    }

                    @Override
                    public void onResponse(Bitmap bitmap, int id) {
                        Log.e("TAG", "onResponse:complete");
                        iv_http.setImageBitmap(bitmap);
                    }
                });
    }

结果:

3.7使用okhttp-utils请求列表图片

既然要在列表中加载图片,就新建一个Activity,使用3.4中的post请求得到返回的数据,利用SharedPreferences存储起来,断网的时候从本地读取数据,调用loadData方法,加载数据。

   if (response != null) {

    CacheUtils.putString(HYOKhttpListActivity.this, url, response);
    loadData(response);

    }

loadData加载数据,此方法中需要调用parseData方法来解析数据,这样做到不同功能的方法相互分离,方便调用,HYOkHttpListAdapter也是非常简单的,里面就调用3.6中的方法加载单张图片,最下面有源代码,不懂的可以查看。

/**
     * 加载数据
     * @param response
     */
    private void loadData(String response) {
        //得到解析后的收据
        DataBean dataBean = parseData(response);
        List<DataBean.ItemData> datas = dataBean.getTrailers();
        if (datas != null && datas.size() > 0) {
            //有数据
            mHYOkHttpListAdapter = new HYOkHttpListAdapter(HYOKhttpListActivity.this, datas);
            mListView.setAdapter(mHYOkHttpListAdapter);
            tv_nodata.setVisibility(View.GONE);
            //显示适配器
        } else {
            ////没有数据
            tv_nodata.setVisibility(View.VISIBLE);
        }
    }

当手机没有网络的时候,从本地读取存储的数据,这就需要稍微修改一下3.4中的post请求方法,但或许是OkHttp本身的原因还是okhttputils的原因,没网的时候图片是不能加载出来的。

/**
     * 使用okhttputils的post请求
     */
    public void postDataByOkhttputils() {
        String cacheValue = CacheUtils.getString(HYOKhttpListActivity.this, url);
        if (!TextUtils.isEmpty(cacheValue)) {
            loadData(cacheValue);
        }
        OkHttpUtils
                .post()
                .url(url)
                .id(100)
                .build()
                .execute(new MyStringCallback());

    }

有网的时候结果,可以看到,ListView上面的图片在加载的时候有跳跃,这也是存在的一个问题。

断开网络结果,图片没有加载出来

时间: 2024-10-09 21:21:41

看了你就会的OkHttp介绍的相关文章

OkHttp介绍

Android系统提供了两种HTTP通信类,HttpURLConnection和HttpClient,HttpURLConnection相对来说比HttpClient难用,google自从2.3版本之后一直推荐使用HttpURLConnection,并且在6.0版本的sdk中直接删掉了HttpClient类. 但是, 上面两个类库和OkHttp比起来就弱爆了, 因为OkHttp不仅具有高效的请求效率,并且节省宽带, 还提供了很多开箱即用的网络疑难杂症解决方案.(据说Android4.4的源码中可

OkHttp基本使用

OkHttp介绍 Android系统提供了两种HTTP通信类,HttpURLConnection和HttpClient,HttpURLConnection相对来说比HttpClient难用,google自从2.3版本之后一直推荐使用HttpURLConnection,并且在6.0版本的sdk中直接删掉了HttpClient类. 但是, 上面两个类库和OkHttp比起来就弱爆了, 因为OkHttp不仅具有高效的请求效率,并且节省宽带, 还提供了很多开箱即用的网络疑难杂症解决方案.(据说Androi

OkHttp配置HTTPS访问+服务器部署

目录 1 概述 2 OkHttp介绍 3 准备工作 4 OkHttp部分 4.1 暴力方案 4.2 推荐方案 4.2.1 HostnameVerifier 4.2.2 X509TrustManager 5 服务器部署 5.1 上传工程 5.2 Tomcat配置 6 验证与源码 7 常见问题 7.1 Tomcat HTTPS无法访问 7.2 OkHttp HTTPS无法访问 8 参考链接 1 概述 OkHttp配置HTTPS访问,核心为以下三个部分: sslSocketFactory() Host

HBase介绍 (1)---数据模型

http://blog.csdn.net/heyutao007/article/details/5766896 BigTable是什么?Google的Paper对其作了充分的说明.字面上看就是一张大表,其实和我们想象的传统数据库的表还是有些差别的.松散数据可以说是介于Map Entry(key & value)和DB Row之间的一种数据.在我使用Memcache的时候,有时候的需求是需要存储的不仅仅是简单的一个key对应一个value,可能我需要类似于数据库表结构中多属性的存储,但是又不会有传

从Chrome源码看浏览器的事件机制

.aligncenter { clear: both; display: block; margin-left: auto; margin-right: auto } .crayon-line span::after { content: " " } p { font-size: 15px; text-indent: 2em } #colorbox.crayon-colorbox,#cboxOverlay.crayon-colorbox,.crayon-colorbox #cboxWr

上门洗车APP --- Androidclient开发 之 项目结构介绍

上门洗车APP --- Androidclient开发 之 项目结构介绍 前言 尽管公司项目较紧,但还是抽空给大家继续更新. o_O"~ 欢迎大家的关注,非常高兴和大家共同学习.前面给大家分享了项目中的以下内容: 上门洗车APP --- Androidclient开发 前言及业务简介 上门洗车APP --- Androidclient开发 之 网络框架封装介绍(一) 上门洗车APP --- Androidclient开发 之 网络框架封装介绍(二) 之前有非常多朋友私信过来说想打包一份源代码学习

Linux rpm 命令参数使用详解[介绍和应用]

RPM是RedHat Package Manager(RedHat软件包管理工具)类似Windows里面的“添加/删除程序” rpm 执行安装包二进制包(Binary)以及源代码包(Source)两种.二进制包可以直接安装在计算机中,而源代码包将会由RPM自动编译.安装.源代码包经常以src.rpm作为后缀名. 常用命令组合: -ivh:安装显示安装进度--install--verbose--hash-Uvh:升级软件包--Update:-qpl:列出RPM软件包内的文件信息[Query Pac

微信游戏《全民炫舞》公司的引擎开发和布料系统技术介绍

微信<全民炫舞>上线了. 整理了一下过去技术开发历史,还有技术ppt,有兴趣看下: 公司游戏引擎技术介绍: http://www.h3d.com.cn/hr/hr.htm 布料系统技术介绍: 2012 China Game Developer Conference大会演讲资料下载: http://www.h3d.com.cn/hr/downlond/QQX52_CGDC.ppt NVIDIA QQ炫舞2 布料技术演示录像地址: http://www.h3d.com.cn/hr/donnlond

游戏开发人员需要看的书籍

编码习惯及设计基础 程序员修炼之道 http://product.dangdang.com/9053091.html 这本书讲解的一些设计原理很实用, 对设计感兴趣的同学可以一看 推荐指数: 5星 图形渲染, 客户端 3D绘图程序设计 http://product.dangdang.com/20567144.html 推荐指数: 3星 Unity3D游戏开发 http://product.dangdang.com/22783514.html 雨松MOMO的早期Unity3D教学, 和他的网站一样