美文网首页
6.2开源框架-retrofit网络框架-详解

6.2开源框架-retrofit网络框架-详解

作者: 205蚁 | 来源:发表于2018-11-18 16:35 被阅读0次

    retrofit源码解析

      1. retrofit使用方式
      1. retrofit源码剖析

    retrofit使用方式: 3个步骤

      1. 在retrofit中通过一个接口作为http请求的api接口
    • 2.创建一个retrofit实例
    • 3.调用api的接口(通过retrofit实例传入java定义的接口,调用接口里面的方法)
        1.接口类:
                public interface NewApi{
                    
                    @GET("REPOS/{owner}/{repo}/contributors")
                    Call<ResponseBody> contributorsBySimpleGetCall(@Path("owner") String owner,@Path("repo") String repo);
                }
                创建一个java接口,定义一个请求方法,然后用注解的形式告诉这是一个Get请求。定义Url时(即注解后面的参数),动态的获取url的方式来进行的 
                
            2.创建实例
                Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("https://api.github.com/")//这里不是完整的
                    .build();
                NewApi repo = retrofit.create(NewApi.class);
            
            3.调用api的接口
                retrofit2.Call<ResponseBody> call = repo.contributorsBySimpleGetCall("userName","path");
                call.enqueue(new retrofit2.Callback<ResponseBody>(){
                    public void onResponse(retrofit2.Call<ResponseBody> call,retrofit2.Response<ResponseBody> response){
                        //
                    }
                    public void onFailure(retrofit2.Call<ResponseBody> call,Throwable t){
                    
                    }
                })
    

    2.retrofit源码剖析

    动态代理模式:

      1. 首先,通过method把它转换成ServiceMethod;
      1. 然后,通过serviceMethod,args获取到okHttpCall对象;
      1. 最后,再把okHttpCall进一步封装并返回Call对象。
        (把okHttpCall传给Adapter来进行retrofit的网络数据获取)

    Retrofit对象build构造模式创建:
    图:

      1. 构造方法:
        1.传入平台信息
        2.将内置的转换器工厂添加到convertFactories里面,它的主要作用就是当使用多种转换器的时候,能够正确的引导retrotfit网络请求所真正需要的数据转换器
        Retrofit build()方法 
            baseUrl == null;
            //1.判空操作。即使没有使用retrofit也必须传入,不能为空
            okhttp3.Call.Factory callFactory = this.callFactory;
            //2.它的作用是用来数据转化的,请求网络会获取数据,这些数据会在callFactory这里转换成我们需要的数据类型 ,如何做到的?
            if(callFactory == null){
                callFactory = new OkHttpClient();
            }
            //3.创建一个网络请求客户端,添加我们想要的属性
            Executor callbackExecutor = this.callbackExcutor;
            //4.回调的执行者,我们所有的Http的call网络请求,从网络获取的数据是在子线程中进行的,子线程的数据需要在ui线程中显示,这个功能由Executor来做。
            if(callbackExecutor == null){
                callbackExecutor = platform.defaultCallbackExecutor();
            }
            List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
            adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
            
            List<Converter.Factory> convertFactories = new ArrayList<>(this.convertFactories);
            
            return new Retrofit(callFactory,baseUrl,convertFActories,adapterFactories,callbackExecutor,validateEagerly);
    
      1. retrofit实例对象craeate(接口.class)
        动态代理在create方法中实现的
        图:
            public <T> T create(final Class<T> service){
                xxx
                return (T)Proxy.newProxyInstance(service.getClassLoader(),new Class<?>[]{service},
                new InvocationHandler(){
                    private final Platform platform = Platform.get();
                    public Object invoke(Object proxy,Method method,Object[] args)throws Throwable{
                        if(method.getDeclaringClass() == Object.class){
                            return method.invoke(this.args);
                        }
                        if(platform.isDefaultMethod(method)){
                            return platform.invokeDefaultMethod(method,service,proxy,args);
                        }
                        ServiceMethod<Object,Object> serviceMethod = (ServiceMethod<Object,Object>) loadServiceMethod(method);
                        OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod,args);
                        return serviceMethod.callAdapter.adapt(okHttpCall);
                        
                    }
                }
                )
            }
    

    怎么实现的,是怎么把定义的java接口转换成一个实例,然后来请求这个实例当中的方法。返回值 return xx

            Proxy代理.newProxyInstance会返回一个代理实例,
                需要传入1.classLoader(类加载器),
                        2.以及类的本身class,
                        3.InvocationHandler处理器(invocation翻译:处理)
                            invoke方法()
                                每当调用代理类方法的时候,这个方法都会被执行
                                参数:Object proxy,Method method,Object[] args
                                    方法,方法参数(object数据)
                                最精髓的地方:
                                    ServiceMethod<Object,Object> serviceMethod = (ServiceMethod<Object,Object>) loadServiceMethod(method);
                                    //
                                    OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod,args);
                                    return serviceMethod.callAdapter.adapt(okHttpCall);
                            
                            
            其中ServiceMethod<?,?> loadServiceMethod(Method method){
                ServiceMethod<?,?> result = serviceMethodCache.get(method);
                if(result !=null) return result;
                
                synchronized(serviceMethodCache){
                    result = serviceMethodCache.get(method);
                    if(result == null){
                        result = new ServiceMethod.Builder<>(this,method).build();
                        //使用Build模式
                        serviceMethodCache.put(method,result);
                        //缓存
                    }
                }
                return result;
            }
    

    相关文章

      网友评论

          本文标题:6.2开源框架-retrofit网络框架-详解

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