简单实用的OkHttp3入门精简教程

简介: 自定义View系列教程00–推翻自己和过往,重学自定义View 自定义View系列教程01–常用工具介绍 自定义View系列教程02–onMeasure源码详尽分析 自定义View系列教程0...

自定义View系列教程00–推翻自己和过往,重学自定义View
自定义View系列教程01–常用工具介绍
自定义View系列教程02–onMeasure源码详尽分析
自定义View系列教程03–onLayout源码详尽分析
自定义View系列教程04–Draw源码分析及其实践
自定义View系列教程05–示例分析
自定义View系列教程06–详解View的Touch事件处理
自定义View系列教程07–详解ViewGroup分发Touch事件
自定义View系列教程08–滑动冲突的产生及其处理


探索Android软键盘的疑难杂症
深入探讨Android异步精髓Handler
详解Android主流框架不可或缺的基石
站在源码的肩膀上全解Scroller工作机制


Android多分辨率适配框架(1)— 核心基础
Android多分辨率适配框架(2)— 原理剖析
Android多分辨率适配框架(3)— 使用指南


本文将用最简的代码和语句介绍OkHttp3的常用基本操作。

准备工作

导入OkHttp3

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

添加权限


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

请注意:假若你看到此处不明白为什么需要做这些准备工作,那么请点击浏览器右上角的八叉 ( X )

Post,Get,上传,下载

package com.cn.okhttp01;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * 原创作者:谷哥的小弟
 * 博客地址:http://blog.csdn.net/lfdfhl
 */
public class MainActivity extends AppCompatActivity {
    public final static String TAG="reborn";
    private static final int REQUEST_CODE = 9527;
    private static String[] PERMISSIONS = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE };
    private Context mContext;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
    }
    private void init(){
        mContext=this;
        verifyStoragePermissions(this);
    }

    private void testOkHttp(){
        testUpload();
    }

    public void verifyStoragePermissions(Activity activity) {
        int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (permission != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(activity, PERMISSIONS, REQUEST_CODE);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case REQUEST_CODE:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    testOkHttp();
                } else {
                    Toast.makeText(mContext, "您未授权存储权限", Toast.LENGTH_LONG).show();
                }
                break;
            default:
        }
    }


    //Get同步请求
    public void testGet1(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    String url="http://blog.csdn.net/lfdfhl";
                    OkHttpClient okHttpClient=new OkHttpClient();
                    Request.Builder requestBuilder=new Request.Builder();
                    requestBuilder.url(url);
                    Request request=requestBuilder.build();
                    Call call=okHttpClient.newCall(request);
                    Response response=call.execute();
                    String result=response.body().string();
                    response.body().close();
                    Log.i(TAG,"测试Get同步请求 "+result);
                }catch (Exception e){

                }
            }
        }).start();
    }

    //Get异步请求
    public void testGet2(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    String url="http://blog.csdn.net/lfdfhl";
                    OkHttpClient okHttpClient=new OkHttpClient();
                    Request.Builder requestBuilder=new Request.Builder();
                    requestBuilder.url(url);
                    Request request=requestBuilder.build();
                    Call call=okHttpClient.newCall(request);
                    call.enqueue(new Callback() {
                        @Override
                        public void onFailure(Call call, IOException e) {

                        }

                        @Override
                        public void onResponse(Call call, Response response) throws IOException {
                            int code=response.code();
                            String result=response.body().string();
                            response.body().close();
                            Log.i(TAG,"code="+code);
                            Log.i(TAG,"测试Get异步请求 "+result);
                        }
                    });
                }catch (Exception e){

                }
            }
        }).start();
    }


    //POST同步请求
    public void testPost1(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    String url="http://106.14.136.52:8080/user/login";
                    OkHttpClient okHttpClient=new OkHttpClient();
                    Request.Builder requestBuilder=new Request.Builder();
                    FormBody.Builder formBodyBuilder=new FormBody.Builder();
                    formBodyBuilder.add("username","andy");
                    formBodyBuilder.add("password","123456");
                    RequestBody requestBody=formBodyBuilder.build();
                    requestBuilder.url(url);
                    requestBuilder.post(requestBody);
                    requestBuilder.addHeader("apikey","81bf9da930c7f9825a3c3383f1d8d766");
                    Request request=requestBuilder.build();
                    Response response=okHttpClient.newCall(request).execute();
                    int code=response.code();
                    String result=response.body().string();
                    response.body().close();
                    Log.i(TAG,"code="+code);
                    Log.i(TAG,"测试Post同步请求 "+result);
                }catch (Exception e){

                }
            }
        }).start();
    }


    //POST异步请求
    public void testPost2(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    String url="http://106.14.136.52:8080/user/login";
                    OkHttpClient okHttpClient=new OkHttpClient();
                    Request.Builder requestBuilder=new Request.Builder();
                    FormBody.Builder formBodyBuilder=new FormBody.Builder();
                    formBodyBuilder.add("username","andy");
                    formBodyBuilder.add("password","123456");
                    RequestBody requestBody=formBodyBuilder.build();
                    requestBuilder.url(url);
                    requestBuilder.post(requestBody);
                    Request request=requestBuilder.build();
                    Call call=okHttpClient.newCall(request);
                    call.enqueue(new Callback() {
                        @Override
                        public void onFailure(Call call, IOException e) {

                        }

                        @Override
                        public void onResponse(Call call, Response response) throws IOException {
                            int code=response.code();
                            String result=response.body().string();
                            response.body().close();
                            Log.i(TAG,"code="+code);
                            Log.i(TAG,"测试Post异步请求 "+result);
                        }
                    });

                }catch (Exception e){

                }
            }
        }).start();
    }

    //下载
    public void testDownload(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    String url="http://img.blog.csdn.net/20161023140032428";
                    final File downloadFile=new File(getExternalCacheDir().toString()+File.separator+"test.jpg");
                    OkHttpClient okHttpClient=new OkHttpClient();
                    Request.Builder requestBuilder=new Request.Builder();
                    requestBuilder.url(url);
                    Request request=requestBuilder.build();
                    Call call=okHttpClient.newCall(request);
                    call.enqueue(new Callback() {
                        @Override
                        public void onFailure(Call call, IOException e) {

                        }

                        @Override
                        public void onResponse(Call call, Response response) throws IOException {
                            if(response.isSuccessful()){
                                InputStream inputStream=response.body().byteStream();
                                FileOutputStream fileOutputStream=new FileOutputStream(downloadFile);
                                int len=0;
                                byte b []=new byte[1024*2];
                                while ((len=inputStream.read(b))!=-1){
                                    fileOutputStream.write(b,0,len);
                                }
                                fileOutputStream.close();
                                inputStream.close();
                            }
                            response.body().close();
                            Bitmap bitmap = BitmapFactory.decodeFile(downloadFile.getAbsolutePath());
                            Log.i(TAG,"width="+bitmap.getWidth());
                            Log.i(TAG,"height="+bitmap.getHeight());
                        }
                    });

                }catch (Exception e){

                }
            }
        }).start();
    }

    //上传
    public void testUpload(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    String url ="http:192.168.0.103:8081/SpringMVC07/testUpload/uploadFile.do";
                    OkHttpClient okHttpClient=new OkHttpClient();
                    MultipartBody.Builder multipartBodyBuilder=new MultipartBody.Builder();
                    //添加文件
                    File file=new File(Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator+"test.jpg");
                    String fileName=file.getName();
                    MediaType mediaType=MediaType.parse("image/*");
                    RequestBody requestBody=RequestBody.create(mediaType,file);
                    multipartBodyBuilder.setType(MultipartBody.FORM);
                    multipartBodyBuilder.addFormDataPart("photo",fileName,requestBody);
                    //添加参数
                    multipartBodyBuilder.addFormDataPart("name","zxx");
                    multipartBodyBuilder.addFormDataPart("number","9527");
                    multipartBodyBuilder.addFormDataPart("country","China");
                    MultipartBody multipartBody=multipartBodyBuilder.build();
                    Request.Builder requestBuilder=new Request.Builder();
                    requestBuilder.url(url);
                    requestBuilder.post(multipartBody);
                    Request request=requestBuilder.build();
                    Call call=okHttpClient.newCall(request);
                    call.enqueue(new Callback() {
                        @Override
                        public void onFailure(Call call, IOException e) {
                            Log.i(TAG,"onFailure");
                        }

                        @Override
                        public void onResponse(Call call, Response response) throws IOException {
                            Log.i(TAG,"onResponse");
                        }
                    });

                }catch (Exception e){

                }
            }
        }).start();
    }

}

请注意:测试时,请将url替换成您自己的可用地址

OkHttp拦截器

package com.cn.okhttp02;

import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * 原创作者:谷哥的小弟
 * 博客地址:http://blog.csdn.net/lfdfhl
 */
public class MainActivity extends AppCompatActivity {
    public final static String TAG="reborn";
    private Context mContext;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
        testApplicationInterceptors();
        testNetworkInterceptors();
    }
    private void init(){
        mContext=this;
    }


    //测试Application Interceptors
    public void testApplicationInterceptors(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    Log.i(TAG,"----> run");
                    String url="http://blog.csdn.net/lfdfhl";
                    OkHttpClient.Builder okHttpClientBuilder= new OkHttpClient.Builder();
                    //添加应用拦截器
                    okHttpClientBuilder.addInterceptor(new LoggingInterceptor());
                    OkHttpClient okHttpClient=okHttpClientBuilder.build();
                    Request.Builder requestBuilder=new Request.Builder();
                    requestBuilder.url(url);
                    requestBuilder.addHeader("os","Android");
                    requestBuilder.addHeader("country","China");
                    Request request=requestBuilder.build();
                    Call call=okHttpClient.newCall(request);
                    call.enqueue(new Callback() {
                        @Override
                        public void onFailure(Call call, IOException e) {
                            Log.i(TAG,"----> onFailure");
                        }

                        @Override
                        public void onResponse(Call call, Response response) throws IOException {
                            Log.i(TAG,"----> onResponse");
                            int code=response.code();
                            String result=response.body().string();
                            response.body().close();
                            Log.i(TAG,"测试Application Interceptors "+result);
                        }
                    });
                }catch (Exception e){

                }
            }
        }).start();
    }


    //测试Network Interceptors
    public void testNetworkInterceptors(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    Log.i(TAG,"----> run");
                    String url="http:www.github.com";
                    OkHttpClient.Builder okHttpClientBuilder= new OkHttpClient.Builder();
                    //添加网络拦截器
                    okHttpClientBuilder.addNetworkInterceptor(new LoggingInterceptor());
                    OkHttpClient okHttpClient=okHttpClientBuilder.build();
                    Request.Builder requestBuilder=new Request.Builder();
                    requestBuilder.url(url);
                    requestBuilder.addHeader("os","Android");
                    requestBuilder.addHeader("country","China");
                    Request request=requestBuilder.build();
                    Call call=okHttpClient.newCall(request);
                    call.enqueue(new Callback() {
                        @Override
                        public void onFailure(Call call, IOException e) {
                            Log.i(TAG,"----> onFailure");
                        }

                        @Override
                        public void onResponse(Call call, Response response) throws IOException {
                            Log.i(TAG,"----> onResponse");
                            int code=response.code();
                            String result=response.body().string();
                            response.body().close();
                            Log.i(TAG,"测试Network Interceptors "+result);
                        }
                    });
                }catch (Exception e){

                }
            }
        }).start();
    }


    class LoggingInterceptor implements Interceptor {
        @Override
        public Response intercept(Interceptor.Chain chain) throws IOException {
            Log.i(TAG,"----> intercept");
            Request request = chain.request();
            long t1 = System.nanoTime();
            Log.i(TAG, "intercept: " + String.format("Sending request %s on %s%n%s",request.url(), chain.connection(), request.headers()));
            Response response = chain.proceed(request);
            long t2 = System.nanoTime();
            Log.i(TAG, "intercept: " + String.format("Received response for %s in %.1fms%n%s",response.request().url(), (t2 - t1) / 1e6d, response.headers()));
            return response;
        }
    }

}

什么是拦截器呢?

拦截器能对Call进行监测、改写、重试连接;它能够对请求和响应进行二次加工。通俗地说:拦截器是请求和回复之间的一道门——发出请求时数据需要从这道门出去;接收响应时数据需要从这道门进来。当然,当数据(不论进出)经过这道门时,该门可对数据进行某些操作。

OkHttp3常用的拦截器分为:

  • Application Interceptors 应用拦截器
  • Network Interceptors 网络拦截器

这两个拦截器有什么区别呢?

Application interceptors 应用拦截器

  • Don’t need to worry about intermediate responses like redirects and retries.
    不关心中间过程的响应,如重定向和重试

  • Are always invoked once, even if the HTTP response is served from the cache.
    总是只调用一次,即使HTTP响应是从缓存中获取

  • Observe the application’s original intent. Unconcerned with OkHttp-injected headers like If-None-Match.
    关注应用程序的初衷. 不关心OkHttp注入的头信息如: If-None-Match.

  • Permitted to short-circuit and not call Chain.proceed().
    允许短路且不调用Chain.proceed()

  • Permitted to retry and make multiple calls to Chain.proceed().
    允许重试,多次调用 Chain.proceed()

Network Interceptors 网络拦截器

  • Able to operate on intermediate responses like redirects and retries.
    能够操作中间过程的响应,如重定向和重试.

  • Not invoked for cached responses that short-circuit the network.
    当网络短路返回缓存响应时不被调用

  • Observe the data just as it will be transmitted over the network.
    只观察在网络上传输的数据.

  • Access to the Connection that carries the request.
    携带请求访问连接

拦截器使用场景

  • 为request统一添加header
  • 检查response判定用户登录信息是否失效,并用Dialog提示用户登录
  • 重写响应头和改变响应体。但不是很推荐这么做,因为可能违反web服务器的期望。
相关文章
|
开发框架 移动开发 小程序
强烈推荐:绝对是好用的小程序开源框架
强烈推荐:绝对是好用的小程序开源框架
184 0
|
4月前
|
设计模式 测试技术 Python
《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
【7月更文挑战第10天】Page Object Model (POM)是Selenium自动化测试中的设计模式,用于提高代码的可读性和维护性。POM将每个页面表示为一个类,封装元素定位和交互操作,使得测试脚本与页面元素分离。当页面元素改变时,只需更新对应页面类,减少了脚本的重复工作和维护复杂度,有利于团队协作。POM通过创建页面对象,管理页面元素集合,将业务逻辑与元素定位解耦合,增强了代码的复用性。示例展示了不使用POM时,脚本直接混杂了元素定位和业务逻辑,而POM则能解决这一问题。
61 6
|
4月前
|
设计模式 Java 测试技术
《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
【7月更文挑战第12天】在本文中,作者宏哥介绍了如何在不使用PageFactory的情况下,用Java和Selenium实现Page Object Model (POM)。文章通过一个百度首页登录的实战例子来说明。首先,创建了一个名为`BaiduHomePage1`的页面对象类,其中包含了页面元素的定位和相关操作方法。接着,创建了测试类`TestWithPOM1`,在测试类中初始化WebDriver,设置驱动路径,最大化窗口,并调用页面对象类的方法进行登录操作。这样,测试脚本保持简洁,遵循了POM模式的高可读性和可维护性原则。
46 2
|
4月前
|
XML Java 测试技术
《手把手教你》系列基础篇(九十一)-java+ selenium自动化测试-框架设计基础-Logback实现日志输出-下篇(详解教程)
【7月更文挑战第9天】在Java项目中,使用Logback配置可以实现日志按照不同包名输出到不同的文件,并且根据日志级别分开记录。
90 4
|
4月前
|
Java 关系型数据库 测试技术
《手把手教你》系列基础篇(八十九)-java+ selenium自动化测试-框架设计基础-Logback实现日志输出-上篇(详解教程)
【7月更文挑战第7天】Apache Log4j2的安全漏洞促使考虑使用logback作为替代的日志框架。Logback由log4j创始人设计,提供更好的性能,更低的内存使用,并且能够自动重载配置文件。它分为logback-core、logback-classic(实现了SLF4J API)和logback-access(用于Servlet容器集成)三个模块。配置涉及Logger、Appender(定义日志输出目的地)和Layout(格式化日志)。
56 1
|
4月前
|
XML 测试技术 数据格式
《手把手教你》系列基础篇(八十五)-java+ selenium自动化测试-框架设计基础-TestNG自定义日志-下篇(详解教程)
【7月更文挑战第3天】TestNG教程展示了如何自定义日志记录。首先创建一个名为`TestLog`的测试类,包含3个测试方法,其中一个故意失败以展示日志。使用`Assert.assertTrue`和`Reporter.log`来记录信息。接着创建`CustomReporter`类,继承`TestListenerAdapter`,覆盖`onTestFailure`, `onTestSkipped`, 和 `onTestSuccess`,在这些方法中自定义日志输出。
50 6
|
5月前
|
Java 测试技术 Python
《手把手教你》系列基础篇(七十九)-java+ selenium自动化测试-框架设计基础-TestNG依赖测试-下篇(详解教程)
【6月更文挑战第20天】TestNG是一个Java测试框架,提供两种测试方法依赖机制:强依赖(所有前置方法成功后才运行)和弱依赖(即使前置方法失败,后置方法仍运行)。文中通过代码示例展示了这两种依赖如何实现,并解释了当依赖方法失败时,如何影响后续方法的执行。文章还包含了TestNG Suite的运行结果截图来辅助说明。
55 8
|
4月前
|
设计模式 Java 测试技术
《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
【7月更文挑战第11天】页面对象模型(POM)通过Page Factory在Java Selenium测试中被应用,简化了代码维护。在POM中,每个网页对应一个Page Class,其中包含页面元素和相关操作。对比之下,非POM实现直接在测试脚本中处理元素定位和交互,代码可读性和可维护性较低。
37 0
|
4月前
|
XML Java 测试技术
《手把手教你》系列基础篇(八十八)-java+ selenium自动化测试-框架设计基础-Log4j 2实现日志输出-下篇(详解教程)
【7月更文挑战第6天】本文介绍了如何使用Log4j2将日志输出到文件中,重点在于配置文件的结构和作用。配置文件包含两个主要部分:`appenders`和`loggers`。`appenders`定义了日志输出的目标,如控制台(Console)或其他文件,如RollingFile,设置输出格式和策略。`loggers`定义了日志记录器,通过`name`属性关联到特定的类或包,并通过`appender-ref`引用`appenders`来指定输出位置。`additivity`属性控制是否继承父logger的配置。
43 0
|
4月前
|
XML Java 测试技术
《手把手教你》系列基础篇(八十七)-java+ selenium自动化测试-框架设计基础-Log4j 2实现日志输出-上篇(详解教程)
【7月更文挑战第5天】Apache Log4j 2是一个日志框架,它是Log4j的升级版,提供了显著的性能提升,借鉴并改进了Logback的功能,同时修复了Logback架构中的问题。Log4j2的特点包括API与实现的分离,支持SLF4J,自动重新加载配置,以及高级过滤选项。它还引入了基于lambda表达式的延迟评估,低延迟的异步记录器和无垃圾模式。配置文件通常使用XML,但也可以是JSON或YAML,其中定义了日志级别、输出目的地(Appender)和布局(Layout)。
47 0