看了下之前4月份寫的Retrofit使用和 源碼分析,發(fā)現(xiàn)县好,源碼這種東西围橡,忘記比較快,只能知道大概是怎么的缕贡,但是從頭去看翁授,花點時間拣播,可以回顧,但是發(fā)現(xiàn)思路比較亂收擦,或許是前一次看了太久了贮配,于是整理下,梳理下
思路整理:
1.創(chuàng)建retrofit
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://fanyi.youdao.com/")
.addConverterFactory(GsonConverterFactory.create())
.build();
1.1第一步 Retrofit :
使用建造者模式建立Retrofit對象 塞赂,首先有個linkedhashMap數(shù)據(jù)結(jié)構(gòu) (后面有原因)存放的 key method value 是ServerMethod 泪勒,這個ServerMethod 是網(wǎng)絡(luò)請求的相關(guān)配置,包括了 baseURL 網(wǎng)絡(luò)請求轉(zhuǎn)換器 網(wǎng)絡(luò)請求適配器 網(wǎng)絡(luò)請求工廠 回調(diào)執(zhí)行器 宴猾,還有就是上面的5個相關(guān)的 網(wǎng)絡(luò)請求工廠 適配器工廠集合 List 轉(zhuǎn)換器工廠集合List 加上一個標(biāo)志 作用是判斷是不是要提前檢查接口注解進行轉(zhuǎn)換酣藻, 第一步 就是配置好這5個 和 linkedhashmap 特別說下 網(wǎng)絡(luò)請求執(zhí)行器(Call)——callAdapter 網(wǎng)絡(luò)請求執(zhí)行器的適配器——適配器是哪里來的?是callAdapterFactory生產(chǎn)的鳍置,在retrofit 中這個適配器有4種辽剧,默認(rèn)的excutorCallAdapterFactory.java8 Guava ,Rxjava,,,,, 在retrofit 中 執(zhí)行器默認(rèn)是okhttpcall 比如要將這個默認(rèn)請求執(zhí)行器轉(zhuǎn)換成不同平臺的 比如rxjava 調(diào)用時候就要添加 add CallFactroy(RxjavacallAdapterFactory.create());
后面的幾個步驟都是為了配置好上面的東西,
1.2.第二步build()
這個類的成員變量和Retrofit的是對應(yīng)的税产,而配置就是通過這個類來配置的怕轿, 無參調(diào)用了自己的有參構(gòu)造,傳入的參數(shù)是PlatForm.get()——get() 返回的是一個靜態(tài)變量辟拷,靜態(tài)變量是調(diào)用——findPlatForm方法撞羽,這個方法中通過calss.forName("adnrod.os.build"),也就是調(diào)用里面靜態(tài)構(gòu)造 判斷這個build .version,sdk.int !=0 就new Android()是安卓平臺創(chuàng)建一個android對象—— android() 繼承platform主要是返回數(shù)據(jù)做線程切換回主線程顯示UI的 重寫了defaultcallBack方法衫冻,這個newHandler 并綁定主線程诀紊,然后post 切換線程 線程切換的流程是 先從第一個重寫的defalutCallAdapter
Factroy 生成一個call對象,然后用這個對象隅俘,enquene(callback )從而調(diào)用第二個重寫方法的excute通過handler完成 ——最后返回一個platForm對象 有參構(gòu)造:首先是接受上面的platform對象邻奠,然后往成員list,存放數(shù)據(jù)轉(zhuǎn)換器factory的为居,添加一個new BuiltInConvers對象 這個是一個內(nèi)置的數(shù)據(jù)轉(zhuǎn)換器碌宴,懟他初始化,
整個是設(shè)置了默認(rèn)值蒙畴。沒有正真為retrofit成員變量賦值
1.3.第3步baseUrl
首先檢查是否為空——然后調(diào)用parse ()這個parse 是第二步 build 的方法檢查一些符號去吧string類型轉(zhuǎn)換成httpurl 贰镣,包括方案scheme,成功呢繼續(xù)膳凝,—— 再調(diào)用 baseUrl(httpurl url) 判斷是否已斜杠結(jié)束 不是報錯碑隆。
這里主要是為build 類的 url成員變量賦值
1.4.第4步
add ConverterFactory( GsonConverterFactory.create())
GsonConverterFactory.create() 創(chuàng)建了一個含有Gson對象實例的GsonConverterFactory,并返回給addConverterFactory()并
addConvertFactory方法蹬音,就是網(wǎng)build類的 轉(zhuǎn)換器工廠list 添加 上面的含有g(shù)son對象的工廠類上煤,
Retrofit默認(rèn)使用Gson進行解析 如果是其他數(shù)據(jù)格式 可以自定義繼承convert factory 就可以
1.5..第5步 build
配置網(wǎng)絡(luò)請求執(zhí)行器,配置回調(diào)方法執(zhí)行器祟绊,網(wǎng)絡(luò)請求適配器工廠楼入,數(shù)據(jù)轉(zhuǎn)換器工廠 然后new Retrofit 返回
建造者模式哥捕,所以開發(fā)者并不需要關(guān)心配置細節(jié)就可以創(chuàng)建好Retrofit實例,
2嘉熊、創(chuàng)建網(wǎng)絡(luò)請求接口實例
1,定義 接受網(wǎng)絡(luò)請求實體類
2.定義接口類
3.接口 j = retofit.create(接口.class)
4.Call<1的對象> call = j .接口中的getCall()
概述:Retrofit使用外觀模式和動態(tài)代理遥赚,調(diào)用create()創(chuàng)建網(wǎng)絡(luò)請求接口的實例,同時通過接口的注解阐肤,進行網(wǎng)絡(luò)請求參數(shù)的配置
create(): 首先判斷是不是接口凫佛,并且只能是實現(xiàn)一個接口 ,然后判斷之前說的那個標(biāo)志位孕惜,是否需要提前校驗愧薛,如果需要,就調(diào)用earlyvalitedMethod() 在這方法中 用到了反射衫画,獲取到所有的方法毫炉,然后獲取到平臺,然后判斷如果不是系統(tǒng)方法削罩。調(diào)用——loadServiceMethod() : 這個方法通過傳入的參數(shù)method 去 Retrofit類中的成員中的那個 LinkedHashMap 中獲取瞄勾,如果為空就直接new ServiceMethod.builder(this,method ).build()并存到map 中, 如果不需要提前驗證就通過后面的動態(tài)代理解析對應(yīng)方法
這個create()返回的就是創(chuàng)建網(wǎng)絡(luò)請求接口的一個動態(tài)代理的方法弥激,調(diào)用并返回請求接口的實例进陡, 目的就是為了去拿到網(wǎng)絡(luò)請求接口上的所有注解, 在invoke() 中業(yè)調(diào)用了loadServiceMethod() —— 吧這個返回的和參數(shù)封裝到new OkhttpCall中—— 再調(diào)用ServiceMethod.callAdapter.adpt(上面封裝的call) 好處是調(diào)用集中到這個invoke 方法中微服,并且獲取到接口上的注解趾疚,方便封裝serviceMethed new ServiceMethod.builder(this,method ).build() 也分3個步驟,一是配置以蕴,2是獲取方法的注解 方法的參數(shù) build 也是從根據(jù)接口方法返回值注解糙麦,獲取對應(yīng)的網(wǎng)絡(luò)請求適配器,適配器參數(shù) 創(chuàng)建對應(yīng)的轉(zhuǎn)換器 然后在遍歷解析方法注解舒裤,也就是調(diào)用ParseMethodAnnotation() 這里面就是解析 get post delate等請求 然后是獲取參數(shù) 數(shù)量喳资。遍歷 給沒個參數(shù) 有個paramshandler 去解析參數(shù)的注解,這個就是 new ServiceMethod.builder(this,method ).build() 配置完網(wǎng)絡(luò)請求參數(shù)(即配置好ServiceMethod對象) 然后封裝到okhttpcall 然后再調(diào)用上面配置完網(wǎng)絡(luò)請求參數(shù)的serviceMethod方法的callAdapter ,的adapt() 安卓默認(rèn)是call Rxjava 是Observable《》
4.Call<1的對象> call = j .接口中的getCall()
j實際是動態(tài)代理的對象并不是正真網(wǎng)絡(luò)請求接口創(chuàng)建的對象腾供, 調(diào)用這個方法時候被動態(tài)代理對象攔截,被proxy.newinstance 攔截調(diào)用自己的indicatorHnadler 的invoke方法鲜滩, 傳入 代理對象proxy method args 接下來反射獲取注解信息結(jié)合agrs 創(chuàng)建serviceMethod對象 最終創(chuàng)建并返回一個OkHttpCall類型的Call對象 okhttp call 是 okhttp 的封裝類伴鳖,但是此時還不能發(fā)送請求,還要創(chuàng)建請求對象徙硅。
3.執(zhí)行網(wǎng)絡(luò)請求
同步請求:OkHttpCall.execute()
異步請求:OkHttpCall.enqueue()
也就是execute包含下面的3個流程
1.根據(jù)前面的paramshandler 解析參數(shù)榜聂,結(jié)合serviceMethod 對象創(chuàng)建一個Request對象
createRawCall()創(chuàng)建okhttp3,的request對象
2.使用ok的request發(fā)送請求。
call.execute()
3.對返回的數(shù)據(jù)使用之前設(shè)置的GsonConvertFactory解析得到一個Response《T》對象
response( call.execute()) 判斷返回狀態(tài)碼 調(diào)用response嗓蘑。success (body )生成 response類
為了提高效率须肆,Retrofit還會對解析過的請求ServiceMethod進行緩存
4.異步的 就有一個進行線程切換從而在主線程處理返回的數(shù)據(jù)結(jié)果 若使用RXjava直接回調(diào)到主線程
區(qū)別:線程切換流程:1.ExcuterCallAdapterFactry 生成一個ExcutercallbackCall
2.調(diào)用1.的enquene (callback) 從而調(diào)用MaindthreadExcuter 的execute()通過handler 切換