学习笔记---网络通信

1.网络通信

网络通信一直是Android项目里比较重要的一个模块,Android开源项目上出现过很多优秀的网络框架,从一开始只是一些对HttpClient和HttpUrlConnection简易封装使用的工具类,到后来Google开源的比较完善丰富的Volley,再到如今比较流行的 Okhttp 、 Retrofit 。

 1.1 网络请求框架对比

网络请求框架对比
请求方式作者包体积增量使用成本特点使用场景

HttpURL

Connection

AndroidSDK       0KB2n需要自己做封装,例如线程池管理、返回的数据解析只有少量网络请求的工具类App
VolleyGoogle57KBn

1.适合网络请求频繁、传输数据量小

2.不适合用来上传文件和下载

3.已停更

之前使用Volley,且无需大文件下载的App
OkHttpsquare公司262KB1.5n

1.可以设置拦截器,支持大文件上传和下载

2.OkHttp基于NIO和Okio,性能更好

3.一般需要二次封装使用

一般比较少直接使用,通常搭配Volley和Retrofit
Retrofitsquare公司343KB2n

具备OkHttp的所有优点,且要更出色

1.restful api设计风格

2.通过注解配置请求,包括请求方法、请求参数、请求头等

3.可以搭配多种Converter将获得的数据解析,支持Gson、jackson、Protobur等

对Retrofit比较熟悉时使用

Retrofit是目前Android平台上,可以说是最热门的网络请求框架,是对OkHttp的一个封装。

详解NIO

详解Okio

1.2 Retrofit使用介绍

 1.2.1 创建用于描述网络请求的接口

interface IUserInfoService {
    
    @GET("users/{uid}/name ")
    fun getUserName(@Path("uid") uid: Int): Call<ResponseBody>

    //后续可以增加其他的接口,一个接口对应一个api请求
}

 定义说明:

  • 接口类名:可自定义,尽量和这类请求的含义相关
  • 函数名:可自定义,需要能识别出该接口的作用,该interface里可以增加多个不同的函数 
  • @GET注解:用于指定该接口的相对路径,并采用Get方法发起请求
  • @Path注解:需要外部调用时,传入一个uid,该uid会替换@GET注解里相对路径的{uid}
  • 返回值Call<ResponseBody>:这里用ResponseBody,我们可以直接拿到请求的String内容如果要自动转为Model类,例如User,这里直接替换为User就好。

1.2.2 发起网络请求

        1.2.2.1 创建Retrofit实例

        1.2.2.2 创建请求接口的实例,并获取到Call实例

        1.2.2.3 调用call.enqueue进行异步请求

        1.2.2.4 处理返回的数据

fun getUserName(view: View) {
    
    //创建 Retrofit实例
    val retrofit = Retrofit.Builder()
        .baseUrl("url") //设置网络请求的Url地址
        .build()

    //创建网络请求接口的实例
    val iUserInfoService = retrofit.create(IUserInfoService::class.java)
    val call = iUserInfoService.getUserName(key)

    //enqueue是异步请求的接口
    call.enqueue(object : Callback<ResponseBody> {
        
       override fun onResponse(call: Call<ResponseBody>,response: Response<ResponseBody>){
           //请求成功时回调
            request_result_tv.text ="请求成功:" + response.body() !!.string()     
        }

       override fun onFailure(call: Call<ResponseBody>,e: Throwable) {
            //请求失败时回调
            request_result_tv.text ="请求失败:" +e.message
        }
        
     }
}

1.3 注解介绍 

注解的处理,一般有3个时机(也就是注解的生命周期@Retention):

1.SOURCE:只有在源码中有效,编译时抛弃,例如前面的@Override

2.CLASS:编译class文件时有效,一般会使用到注解处理器。

3.RUNTIME:在运行期间,获取对应的注解,并做相关的处理。

1.3.1 Retrofit注解@GET定义

@Documented
@Target(METHOD)
@Retention(RUNTIME)
public @interface GET {
  /**
   * A relative or absolute path, or full URL of the endpoint. This value is optional if the first
   * parameter of the method is annotated with {@link Url @Url}.
   *
   * <p>See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how
   * this is resolved against a base URL to create the full endpoint URL.
   */
  String value() default "";
}

@Target:指定作用的对象,这里是METHOD,

说明这个注解是作用在方法上其他枚举值:

PARAMETER:参数

FIELD:类成员

@Retention:指定注解的生命周期,这里是RUNTIME,说明要这个注解要一直保留到运行时

1.3.2 注解的获取和使用 

通过反射获取到Method对象后,有以下一些接口来获取注解内容1.Method.getGenericReturnType()获取返回类型

2.Method.getAnnotations()获取方法的注解

3.Method.getParameterAnnotations()获取参数注解

Method[] declaredMethods = IUserInfoService.class.getDeclaredHethods();

for (Method method : declaredMethods) {
    
    Type type = method.getGenericReturnType();//正式返回类型
    Annotation[] methodAnnotations = method.getAnnotations();//方法注解
    Annotation[][] parameterAnnotationsArray = method. getParameterAnnotations();//方法参数注解
   
}

 1.3.3 Java动态代理Proxy.newProxylnstance

  • 利用Java的反射技术(Java Reflection),代理某个interface,一旦调用interface里的某个方法时,实际通过代理调用InvocationHandler的invoke方法
  • 通过Method对象,就可以调用Method.getAnnotations()和Method.getParameterAnnotations()来获取该方法和方法参数的注解内容。
public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h)
    throws IllegalArgumentException
    

 

public interface InvocationHandler {
    public Object invoke (Object proxy , Method method , Object[] args)
        throws Throwable;
}

 Retrofit是在运行期间,配合Java动态代理,获取方法和参数的注解,并构造Request对象的。

1.4 Retrofit主流程 

1.通过Builder模式,创建RetrofitConfig,保存baseUrl等内容

2.创建动态代理对象

3.创建OkHttpCall

4.发起网络请求

 1.4.1 Retrofit里OkHttpClient创建时机

Retrofit的Builder构造行数中如果未指定callFactory,则会自动创建一个OKHttpClient

注:这里留意下,有一个adapterFactories集合,里面包含一个默认的CallAdapter.Factory ,它是子类ExecutorCallAdapterFactory的实例

 1.4.2 Retrofit里OkHttpClient创建时机

创建好的OKHttpClient将会保存在Retrofit实例中

ExecutorCallAdapterFactory主要是用来控制Retrofit在子线程触发请求,在主线程回调结果

 

1.4.3 OkHttpCall的创建

当我们通过代理对象调用我们的接口方法lUserlnfoService#getUserName()时,会触发lnvocationHandler#invoke方法

下图可以看到Retrofit写死了只支持OkHttp

 

 1.5 TTNet类图设计

核心点主要替换其中的两点:

1.替换底层用到的OKHttpClient

2.替换底层用到的OKHttpCall 

 

 总结

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值