Android

网络框架Retrofit(一)--了解封装的Okhttp

2020-08-31  本文已影响0人  jeffrey12138

对于网络框架,一直都处于一知半解的状态,所以除了基本的应用之外,怎么延伸都不知从何下手,于是,我就抽时间进一步的去了解:
众所周知,retrofit是对okhttp进行封装,而retrofit只是简单的去使用okhttp的框架,但是想更深入了解网络请求,建议还是先从okhttp进行了解,所以下面我会先去了解okhttp:
1、导入okhttp:
访问https://github.com/square/okhttp

image.png
获取最新版本的okhttp,进入项目的build.gradle添加依赖

2、根据官网的提示去使用okhttp


image.png

发现出现这样的报错,那是因为最新的okhttp要求的最低版本是21以及jdk版本为8.0,解决方案如下:


image.png

顺便说下怎么找到对应的配置方法,可以在官网里面看到作者写的android-text文档,然后点开他的build.gradle,就可以看到作者是怎么配置,那样就可以拿到最新的配置。

还有需要说明下:因为android9.0及以上的版本会默认不予许直接方法http的,因为官网觉得这样不安全,所以需要做如下的配置:
①访问官网:
https://developer.android.com/training/articles/security-config

image.png
然后往下面拉的话,就会看到各种证书的添加方法,我就直接上我的吧:
<network-security-config>
    <base-config cleartextTrafficPermitted="true">//支持访问HTTP协议的
        <trust-anchors>
            <certificates src="system" />//信任系统里面内置的CA证书
            <certificates src="user" />//信任用户自己安装的证书,这个是为了抓包软件可以正常工作,记得还要安装抓包的插件
        </trust-anchors>
    </base-config>
</network-security-config>

3、添加okhttp拦截器,打印我们构造出来的请求和已接收到结果,在官网中okhttp-logging-interceptor这个文档中就可以看到怎添加使用
然后下面就直接上代码了,代码细节都写在里面,好好看哈:
build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.3"

    defaultConfig {
        applicationId "com.example.retrofit"
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
    implementation("com.squareup.okhttp3:okhttp:4.8.1")
    implementation("com.squareup.okhttp3:logging-interceptor:4.8.1")
}

INetCallBack

public interface INetCallBack {
    void onSuccess(String response);

    void onFailed(Throwable ex);
}

OkhttpUtils

public class OkhttpUtils {
    private OkHttpClient client;
    private OkhttpUtils(){
        //添加拦截器
        HttpLoggingInterceptor logging = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                Log.d("jeffrey",message);
            }
        });
        logging.setLevel(HttpLoggingInterceptor.Level.BODY);
         client = new OkHttpClient.Builder()
                 .addInterceptor(new AuthIntercetor())
                .addInterceptor(logging)
                .build();
    }
    private static OkhttpUtils sInstance=new OkhttpUtils();
    //对外公开一个获取方法
    public  static  OkhttpUtils getInstance(){
        return sInstance;
    }
    private Handler mUiHandler=new Handler(Looper.getMainLooper());

/*    //同步请求
    public String doGet(String url){

        try {
            //1、构造OkHttpClient对象;
            OkHttpClient client=new OkHttpClient();
            //2.通过Request.Builder()去构造Request对象;
            Request request=new Request.Builder()
                    .url(url)
                    .build();
            //3、通过Request对象去拿到Call对象;
            Call call=client.newCall(request);

            //4.通过Call对象执行去拿到Response对象
            Response response = call.execute();
            return response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }*/
//异步请求
    public void doGet(String url,HashMap<String,String> headers,INetCallBack callBack){
        //添加请求头信息
        Request.Builder builder=new Request.Builder();
        if (headers !=null){
            for (String key:headers.keySet()){
                builder.addHeader(key,headers.get(key));
            }
        }
        Request request=builder
                .url(url)
                .build();
        executeRequest(callBack, request);
    }



    //注意下POST请求的参数不是接到url后面的,所以需要参数2
    public void doPost(String url, HashMap<String,String> headers,HashMap<String,String> params,INetCallBack callBack){
        FormBody.Builder formBodyBuilder=new FormBody.Builder();
        if (params!=null){
            for (String param:params.keySet()){
                formBodyBuilder.add(param,params.get(param));
            }
        }
        Request.Builder requsetBuilder=new Request.Builder();
        if (headers !=null){
            for (String key:headers.keySet()){
                requsetBuilder.addHeader(key,headers.get(key));
            }
        }
        Request request = requsetBuilder
                .url(url)
                .post(formBodyBuilder.build())
                .build();
        executeRequest(callBack, request);
    }

    public void doPostMultiPart(String url,HashMap<String,String> headers, HashMap<String,String> params,INetCallBack callBack){
        MultipartBody.Builder multipartBodyBuilder=new MultipartBody.Builder();
        multipartBodyBuilder.setType(MultipartBody.FORM);
        if (params!=null){
            for (String param:params.keySet()){
                multipartBodyBuilder.addFormDataPart(param,params.get(param));
            }
        }
        Request.Builder requsetBuilder=new Request.Builder();
        if (headers !=null){
            for (String key:headers.keySet()){
                requsetBuilder.addHeader(key,headers.get(key));
            }
        }
        Request request=requsetBuilder
                .url(url)
                .post(multipartBodyBuilder.build())
                .build();
        executeRequest(callBack, request);
    }

    public void doPostJson(String url,HashMap<String,String> headers,String jsonStr,INetCallBack callBack){
        //MediaType代表jSon字符串所含的格式
        MediaType jsonMediaType=MediaType.get("application/json");
        RequestBody requestBody=RequestBody.create(jsonStr,jsonMediaType);
        Request.Builder requsetBuilder=new Request.Builder();
        if (headers !=null){
            for (String key:headers.keySet()){
                requsetBuilder.addHeader(key,headers.get(key));
            }
        }
        Request request=requsetBuilder
                .url(url)
                .post(requestBody)
                .build();
        executeRequest(callBack, request);
    }

    private void executeRequest(INetCallBack callBack, Request request) {
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                mUiHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        callBack.onFailed(e);
                    }
                });
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                //注意response.body().string()也是耗时操作,所以要拿出来
                String respStr = null;
                try {
                    respStr = response.body().string();
                } catch (IOException e) {
                    mUiHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            callBack.onFailed(e);
                        }
                    });
                    return;
                }

                String finalRespStr = respStr;
                mUiHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        callBack.onSuccess(finalRespStr);
                    }
                });

            }
        });
    }
}

AuthIntercetor

public class AuthIntercetor implements Interceptor {
    @NotNull
    @Override
    public Response intercept(@NotNull Chain chain) throws IOException {

        Request originRequest=chain.request();
        Request newRequest=originRequest.newBuilder()
                .addHeader("author","jeffrey")
                .build();
        return chain.proceed(newRequest);
    }
}

MainActivity

public class MainActivity extends AppCompatActivity {
    private Button mBtnGet,mBtnPost,mBtnPostMultipart,mBtnPostJson;
    private TextView mTvContent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initViews();
        initEvents();
    }

    private void initEvents() {
        mBtnGet.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                HashMap<String,String> headers=new HashMap<>();
                headers.put("author_headr","jeffer");
                OkhttpUtils.getInstance()
                        .doGet("",headers, new INetCallBack() {
                            @Override
                            public void onSuccess(String response) {
                                mTvContent.setText(response);
                            }

                            @Override
                            public void onFailed(Throwable ex) {
                                Toast.makeText(MainActivity.this,"网络发生错误",Toast.LENGTH_SHORT).show();
                            }
                        });
               /* //发送网络请求
                new Thread(){
                    @Override
                    public void run() {
                        super.run();
                        String content=OkhttpUtils.getInstance().
                                doGet("");
                        mUiHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                mTvContent.setText(content);
                            }
                        });
                    }
                }.start();*/
            }
        });
        mBtnPost.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                HashMap<String,String> headers=new HashMap<>();
                headers.put("author_headr","jeffer");
                HashMap<String,String> params=new HashMap<>();
                params.put("author","jeffrey");
                params.put("abc","xyz");
                OkhttpUtils.getInstance().doPost("", headers,null, new INetCallBack() {
                    @Override
                    public void onSuccess(String response) {
                        mTvContent.setText(response);
                    }

                    @Override
                    public void onFailed(Throwable ex) {
                        Toast.makeText(MainActivity.this,"网络发生错误",Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });
        mBtnPostMultipart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                HashMap<String,String> headers=new HashMap<>();
                headers.put("author_headr","jeffer");
                HashMap<String,String> params=new HashMap<>();
                params.put("author","jeffrey");
                params.put("abc","xyz");
                OkhttpUtils.getInstance().doPostMultiPart("", headers,null, new INetCallBack() {
                    @Override
                    public void onSuccess(String response) {
                        mTvContent.setText(response);
                    }

                    @Override
                    public void onFailed(Throwable ex) {
                        Toast.makeText(MainActivity.this,"网络发生错误",Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });
        mBtnPostJson.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                HashMap<String,String> headers=new HashMap<>();
                headers.put("author_headr","jeffer");
                OkhttpUtils.getInstance().doPostJson("", headers,"{\"name\":\"jeffrey\",\"age\":18}", new INetCallBack() {
                    @Override
                    public void onSuccess(String response) {
                        mTvContent.setText(response);
                    }
                    @Override
                    public void onFailed(Throwable ex) {
                        Toast.makeText(MainActivity.this,"网络发生错误",Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });
    }

    private void initViews() {
        mBtnGet=findViewById(R.id.bt_get);
        mTvContent=findViewById(R.id.tv_content);
        mBtnPost=findViewById(R.id.bt_post);
        mBtnPostMultipart=findViewById(R.id.bt_post_multipart);
        mBtnPost=findViewById(R.id.bt_post_json);
    }
}

这里我小结一下:
1、其实从开头就开始说如何从文档中读取使用方法,是建议大家真的多去官网看文档,因为很多时候看别人的文章,都是别人总结好的东西,很难去了解所用的框架后面怎么去拓展,所以,最好还是以官网的文档使用为准会比较好;
2、okttp的使用步骤其实就是:
①、构造OkHttpClient对象;
②、通过Request.Builder()去构造Request对象;
③、通过Request对象去拿到Call对象;
④、通过Call对象执行去拿到Response对象
好啦!下一章,我会说下Retrofit的用法,然后进行对比,尽量让大家可以一眼就看透他们的对比性,觉得写得可以话,请关注和点赞哦!!

上一篇下一篇

猜你喜欢

热点阅读