Android框架学习笔记01Okhttp框架

Google在Android6.0之后就删除了HttpClient相关的API,使用HttpUrlConnection代替,在Android开发中,网络访问是必不可少的,网络上也有很多网络操作的框架,这一篇,我们介绍一下网络上非常火的一个网络框架——Okhttp框架。

概述

Okhttp现在已经出到3.4.1版本,主要包含的功能有:

  • 一般的get请求

  • 一般的post请求

  • 基于Http的文件上传

  • 文件下载

  • 加载图片

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

  • 支持session的保持

下面我们介绍一下Okhttp的简单使用:

使用

使用Okhttp需要在项目的gradle文件中导入包,直接添加如下代码:

 compile 'com.squareup.okhttp3:okhttp:3.4.1'

不过建议先去okhttp的github上查看最新的版本,okhttp的github地址是:https://github.com/square/okhttp

使用Eclipse的话需要下载相应的JAR包,也可以到上述地址下载。

还有需要在清单文件中添加联网的权限

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

完成准备工作之后,我们就而已开始使用这个网络框架了,下面我们通过具体的例子实现以下okhttp的各种功能:

实现异步GET请求

     //异步get请求
    findViewById(R.id.tv_async_get).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            OkHttpClient okHttpClient = new OkHttpClient();
            Request.Builder builder = new Request.Builder();
            Request request = builder.url("http://blog.csdn.net/lmj623565791/article/details/49734867").method("GET", null).build();
            Call call = okHttpClient.newCall(request);
            //回调监听
            call.enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(MainActivity.this, "异步get请求失败", Toast.LENGTH_SHORT).show();
                        }
                    });
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                //    if (response.cacheResponse() != null) {
                //  String str = response.cacheResponse().toString();
                //     Log.i(TAG, "onResponse" + str);
                //   } else {
                //   String str = response.networkResponse().toString();
                //   Log.i(TAG, "onResponse" + str);
                //   }

                    Log.i(TAG, "===============================================================================");
                    String str = response.body().string();
                    Log.i(TAG, "onResponse" + str);
                    Log.i(TAG, "===============================================================================");

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(MainActivity.this, "异步get请求成功", Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            });

        }
    });

这里就是构建一个请求回调,不过回调不是在主线程,所以不能直接更新UI

实现同步GET请求

    //同步get请求
    findViewById(R.id.tv_sync_get).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            new Thread(new Runnable() {
                @Override
                public void run() {
                    OkHttpClient okHttpClient = new OkHttpClient();
                    Request.Builder builder = new Request.Builder();
                    Request request = builder.url("http://www.baidu.com").method("GET", null).build();
                    Call call = okHttpClient.newCall(request);
                    try {
                        Response response = call.execute();
                        if (response.isSuccessful()) {

                            Log.i(TAG, "=======================================================");
                            Log.i(TAG, "run" + response.body().string());
                            Log.i(TAG, "=======================================================");
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Log.i(TAG, "同步get请求成功");
                                    Toast.makeText(MainActivity.this, "同步get请求成功", Toast.LENGTH_SHORT).show();
                                }
                            });
                        } else {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Log.i(TAG, "同步get请求失败");
                                    Toast.makeText(MainActivity.this, "同步get请求失败", Toast.LENGTH_SHORT).show();
                                }
                            });
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            }).start();

        }
    });

同步GET请求和异步GET请求最大的区别就是调用不同的方法,同步调用的是execute,而异步调用的是enqueue,网络请求不能主线程中。

实现异步POST请求

客户端代码:

     //异步post请求
    findViewById(R.id.tv_async_post).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            OkHttpClient okHttpClient = new OkHttpClient();
            RequestBody formBody = new FormBody.Builder().add("username", "zhangsan")
                    .add("password", "zhangsan").build();
            Request resuest = new Request.Builder().post(formBody).url("http://192.168.0.218:8080/sayHello").build();
            Call call = okHttpClient.newCall(resuest);
            call.enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(MainActivity.this, "服务器无法连接", Toast.LENGTH_SHORT).show();
                        }
                    });
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(MainActivity.this, "post请求成功", Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            });
        }
    });

服务器端:

服务器端我是用Intelij IDEA2016写的,就是简单实现上传两个字符串而已,代码也非常简单。

实现异步下载文件

     //异步下载文件
    findViewById(R.id.tv_async_download_file).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            OkHttpClient okHttpClient = new OkHttpClient();
            Request request = new Request.Builder().url("http://192.168.0.218:8080/okhttp-3.4.1.jar").build();
            okHttpClient.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(MainActivity.this, "下载失败,请稍后重试", Toast.LENGTH_SHORT).show();
                        }
                    });
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    InputStream inputStream = response.body().byteStream();
                    FileOutputStream fileOutputStream = null;
                    fileOutputStream = new FileOutputStream(new File("/sdcard/okhttp-3.4.1.jar"));
                    byte[] bytes = new byte[1024];
                    int len = 0;
                    while ((len = inputStream.read(bytes)) != -1) {
                        fileOutputStream.write(bytes, 0, len);
                    }
                    fileOutputStream.flush();
                    Log.i(TAG, "onResponse----->>文件下载成功");

                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(MainActivity.this, "文件下载成功", Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            });

        }
    });

实现的效果如下:

实现异步上传文件

         //异步上传文件
    findViewById(R.id.tv_async_upload_file).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            MediaType mime = MediaType.parse("application/java-archive;charset=utf-8");
            String url = "http://192.168.0.218:8080/upload";
            OkHttpClient okHttpClient = new OkHttpClient();
            File file = new File("/sdcard/okhttp-3.4.1.jar");
            Request request = new Request.Builder().url(url).post(RequestBody.create(mime, file)).build();
            okHttpClient.newCall(request).enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    Log.i(TAG, "onResponse---->>上传失败");
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(MainActivity.this, "文件上传失败", Toast.LENGTH_SHORT).show();
                        }
                    });
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    Log.i(TAG, "onResponse---->>上传成功");
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(MainActivity.this, "文件上传成功", Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            });
        }
    });

文件上传需要用服务器接收,这里我是自己写一个简单的Servlet去接收的,实际开发肯定会有服务器接收的。这里需要注意的是需要设置文件的MIME类型,如果不知道相应后缀名的文件的MIME类型,可以去这里查看一下:http://www.cnblogs.com/linyijia/p/5466317.html

请求超时设置

与前面版本不同的是,3.0之后就不再允许直接通过OkhttpClient设置超时了,而是通过OkHttpClient.Builder设置,设置好之后我们可以直接通过builder.build获取到一个OkHttpClient,这样我们就不再需要new一个OkHttpClient。请看下面的代码:

OkHttpClient.Builder builder = new OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .writeTimeout(20, TimeUnit.SECONDS)
            .readTimeout(20, TimeUnit.SECONDS)
            .cache(new Cache(sdcache.getAbsoluteFile(), cacheSize));
    OkHttpClient mOkHttpClient=builder.build();  

取消请求和简单封装

可以直接调用call.cancel()取消掉请求,这个框架的二次封装网上有很多,这里就不再贴代码了,关于这个框架就简单介绍到这里了,推荐几篇关于这个框架的介绍博文:

Android 一个改善的okHttp封装库

OkHttp3源码分析

okhttp3与旧版本okhttp的区别分析

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容