Retrofit框架源碼分析一

 

Retrofit框架源碼分析一

 

Retrofit基本使用

第一步:

    //先引入依賴,(這裏不需要另外引入OkHttp依賴,因爲Retrofit默認內置)
    //第一個,retrofit依賴
    implementation 'com.squareup.retrofit2:retrofit:2.6.0'
    //第二個,用於GsonConverterFactory
    implementation 'com.squareup.retrofit2:converter-gson:2.6.0'
    //第三個,CallAdapterFactory用於RxJava,可以不引入
    implementation 'com.squareup.retrofit2:adapter-rxjava:2.6.0'



//然後添加網絡權限
    <uses-permission android:name="android.permission.INTERNET"/>

第二步:新建服務器響應回來的實體類MyResponse


//請求接口爲:http://api.nnzhp.cn/api/user/stu_info/
//響應內容爲:{
//        "error_code": 3001,
//        "msg": "必填參數未填!請查看接口文檔!"
//}

public class MyResponse {

    /**
     * error_code : 3001
     * msg : 必填參數未填!請查看接口文檔!
     */

    private int error_code;
    private String msg;

    public int getError_code() {
        return error_code;
    }

    public void setError_code(int error_code) {
        this.error_code = error_code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

第三步:新建接口類MyInterface

//這裏傳入請求的路勁,以及響應實體類。
public interface MyInterface {
    @GET("user/stu_info/")
    Call<MyResponse> getCall();
}

第四步:發送請求,獲取服務器數據

// url必須以 / 結尾,addCallAdapterFactory可以不添加。
Retrofit retrofit=new Retrofit.Builder()
                .baseUrl("http://api.nnzhp.cn/api/")
                //設置數據轉換器Gson
                .addConverterFactory(GsonConverterFactory.create())
                //設置支持RxJava
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();

        MyInterface myInterface=retrofit.create(MyInterface.class);
        Call<MyResponse> call=myInterface.getCall();
        call.enqueue(new Callback<MyResponse>() {
            @Override
            public void onResponse(Call<MyResponse> call, Response<MyResponse> response) {
                Log.d("crook",response.body().getMsg());
            }

            @Override
            public void onFailure(Call<MyResponse> call, Throwable t) {

            }
        });

//輸出結果爲:
//crook: 必填參數未填!請查看接口文檔!

具體源碼解析:

//new Retrofit.Builder()中的Builder()方法的實現,最終調用如下方法
//獲取支持的平臺,Android
private static Platform findPlatform() {
    try {
      //查找類名爲android.os.Build的類,如果拋出異常,說明沒有找到。
      Class.forName("android.os.Build");
      if (Build.VERSION.SDK_INT != 0) {
        return new Android();
      }
    } catch (ClassNotFoundException ignored) {
    }
    
  }

 


// .baseUrl("http://api.nnzhp.cn/api/")方法的實現
public Builder baseUrl(String baseUrl) {
      checkNotNull(baseUrl, "baseUrl == null");
      //將String類型的url轉換成HttpUrl類型
      return baseUrl(HttpUrl.get(baseUrl));
    }
//最終調用下面的baseUrl方法
public Builder baseUrl(HttpUrl baseUrl) {
      
      List<String> pathSegments = baseUrl.pathSegments();
      
      //baseurl必須以斜槓結尾
      if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
        throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
      }
      
      return this;
    }
//.addConverterFactory(GsonConverterFactory.create())方法的實現

 public Builder addConverterFactory(Converter.Factory factory) {

      //將factory添加至converterFactories集合
      converterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }

// GsonConverterFactory.create()方法的實現
public static GsonConverterFactory create(Gson gson) {
    if (gson == null) throw new NullPointerException("gson == null");
    //new Gson然後傳入
    return new GsonConverterFactory(gson);
  }
// .addCallAdapterFactory(RxJavaCallAdapterFactory.create())方法的實現


 public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
      //將數據適配器工廠添加至集合
      callAdapterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }

// .build()方法的實現
// 將前面創建的對象,以及創建的默認對象,傳入new Retrofit()的構造方法

public Retrofit build() {
     
      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) {
        callFactory = new OkHttpClient();
      }

      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
        callbackExecutor = platform.defaultCallbackExecutor();
      }

      return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
          unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
    }

Retrofit是封裝了OkHttp的RESTFUL風格的網絡請求框架,通過動態代理將Java接口轉換成HTTP請求。所以,如果想弄清楚原理,首先要理解代理模式,尤其是動態代理。

 

靜態代理

//新建一個接口Subject
public interface Subject {
    public void myFunc(String arg);
}



//新建一個目標類,並實現接口Subject
public class RealSubject implements Subject {
    @Override
    public void myFunc(String arg) {
        System.out.println("RealSubject:"+arg);
    }
}


//新建一個代理類,並調用目標類
public class SubjectProxy implements Subject {
    private RealSubject realProxy = new RealSubject();
    @Override
    public void myFunc(String arg) {
        realProxy.myFunc(arg);
    }
}



//測試靜態代理的類
public class MyClass {
    public static void main(String [] a){
        SubjectProxy subjectProxy=new SubjectProxy();
        subjectProxy.myFunc("靜態代理");
 
    }
}



//測試結果:
RealSubject:靜態代理



 

動態代理:

//新建動態代理類
public class ProxyHandler implements InvocationHandler {

    private Object mTarget;
    public Object bind(Object target){
        mTarget=target;
        return Proxy.newProxyInstance(mTarget.getClass().getClassLoader(),
                mTarget.getClass().getInterfaces(),this);
    }

    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        Object result=null;
        System.out.println("動態代理:方法調用之前");
        result=method.invoke(mTarget,objects);
        System.out.println("動態代理:方法調用之後");
        return result;
    }
}



//測試類
public static void main(String [] a){       
        ProxyHandler proxyHandler=new ProxyHandler();
        //傳入目標類RealSubject
        Subject subject= (Subject) proxyHandler.bind(new RealSubject());
        subject.myFunc("動態代理");

    }
}


//測試結果
動態代理:方法調用之前
RealSubject:動態代理
動態代理:方法調用之後


 

// MyInterface myInterface=retrofit.create(MyInterface.class)
//中create()方法的實現
public <T> T create(final Class<T> service) {
    
//動態代理
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
        new InvocationHandler() {          

          @Override public @Nullable Object invoke(Object proxy, Method method,
              @Nullable Object[] args) throws Throwable {
            //返回ServiceMethod
            return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
          }
        });
  } 

//loadServiceMethod()方法的實現
ServiceMethod<?> loadServiceMethod(Method method) {
    //從serviceMethodCache集合中獲取,如果沒有獲取到,則重新創建
    ServiceMethod<?> result = serviceMethodCache.get(method);
    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
        //沒有獲取到serviceMethod,則重新創建並存放serviceMethodCache集合作爲緩存。
        result = ServiceMethod.parseAnnotations(this, method);
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

//ServiceMethod.parseAnnotations(this, method)方法的實現
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
    Type returnType = method.getGenericReturnType();
    //繼續調用
    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }


//HttpServiceMethod.parseAnnotations()方法的實現
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
//首先創建CallAdapter
CallAdapter<ResponseT, ReturnT> callAdapter =
        createCallAdapter(retrofit, method, adapterType, annotations);

//然後創建數據轉換器
Converter<ResponseBody, ResponseT> responseConverter =
        createResponseConverter(retrofit, method, responseType);
}


//createCallAdapter()方法最終調用nextCallAdapter()方法
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
      Annotation[] annotations) {
   
    int start = callAdapterFactories.indexOf(skipPast) + 1;
//從集合callAdapterFactories中獲取CallAdapter
    for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
      CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
      if (adapter != null) {
        return adapter;
      }
    }

    
  }

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章