美文网首页Android
网络框架Retrofit(一)--了解封装的Okhttp

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

作者: jeffrey12138 | 来源:发表于2020-08-31 19:33 被阅读0次

    对于网络框架,一直都处于一知半解的状态,所以除了基本的应用之外,怎么延伸都不知从何下手,于是,我就抽时间进一步的去了解:
    众所周知,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的用法,然后进行对比,尽量让大家可以一眼就看透他们的对比性,觉得写得可以话,请关注和点赞哦!!

    相关文章

      网友评论

        本文标题:网络框架Retrofit(一)--了解封装的Okhttp

        本文链接:https://www.haomeiwen.com/subject/ulsusktx.html