升級okhttp3.0+和retrofit2.0+的過程以及遇到的坑
包名變化
okhttp3.0之前是:com.squareup.okhttp.*,
而到3.0之後變成:okhttp3.*
retrofit2.0之前:retrofit.*
retrofit2.0之後:retrofit2.*
都在末尾增加了版本號,顯示的更專業,但是這也給我們升級帶來了麻煩。
首先看一下retrofit1.9+okhttp2.2的配置程式碼
okhttp3.0以及retrofit2.0均採用了builder構建者模式配置public class MainRetrofit { final MeoHttp mService; final Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").serializeNulls().create(); RequestInterceptor requestInterceptor = new RequestInterceptor() { @Override public void intercept(RequestFacade request) { request.addHeader("User-Agent", AppConstants.USER_AGENT); request.addHeader("X-Requested-With", "XMLHttpRequest"); request.addHeader("Cookie", AppConstants.PHPSESSID); } }; MainRetrofit() { OkHttpClient client = new OkHttpClient(); client.setReadTimeout(41, TimeUnit.SECONDS); RestAdapter restAdapter = new RestAdapter.Builder() .setClient(new OkClient(client)) .setEndpoint(MainFactory.HOST) .setConverter(new GsonConverter(gson)) .setLogLevel(RestAdapter.LogLevel.NONE) .setRequestInterceptor(requestInterceptor) .build(); mService = restAdapter.create(MeoHttp.class); } public MeoHttp getService(){ return mService; } }
而且retrofit2.0沒有列印日誌的功能,所以只能在okhttp的攔截器裡列印日誌final RequestApi api; final Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").serializeNulls().create(); Interceptor requestInterceptor; private static final okhttp3.OkHttpClient.Builder httpClient = new OkHttpClient.Builder(); public MainRetrofit(final boolean hasCookie) { httpClient.readTimeout(60, TimeUnit.SECONDS). connectTimeout(2, TimeUnit.SECONDS).build(); requestInterceptor = new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); String cookie = ""; if (hasCookie) { cookie = AppConfig.Net.COOKIE_HEAD + CookieManager.getCookie(); } Request compressedRequest = request.newBuilder() .header("Cookie", cookie) .header("Accept-Language", Locale.getDefault().toString()) .header("Accept-Charset", "utf-8") .header("Connection", "Keep-Alive") .header("User-Agent", getUserAgent()) .build(); Response response = chain.proceed(compressedRequest); return response; } }; httpClient.interceptors().add(requestInterceptor); OkHttpClient okHttpClient = httpClient.build(); Retrofit client = new Retrofit.Builder() .baseUrl(AppConfig.Net.HOST) .addConverterFactory(new ScalarsConverterFactory()) .addConverterFactory(GsonConverterFactory.create(gson)) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .client(okHttpClient) .build(); //retrofit 沒有日誌列印功能 /*if (AppConfig.IS_DEVELOPING) { //日誌可用 client.setLogLevel(RestAdapter.LogLevel.FULL); } else { client.setLogLevel(RestAdapter.LogLevel.NONE); }*/ api = client.create(RequestApi.class);
retrofit1.9的介面呼叫方式:
GET:
/** * 獲得使用者地址 */ @GET("/user/Address?") void getAddress(Callback<AddressInfo>callback);
POST:
/** * 上傳畫作 * @param content 圖集描述 * @param atk token值 * @param file 檔案 */ @Multipart @POST("/user/uploadPicture?") void upLoadPaint而對應2.0之後的方式是這樣的(@Part("content")String content, @Part("t")String atk, @Part("upfile") TypedFile file, Callback<BaseResponse> callback);
GET:
/** * 獲得使用者地址 */ @GET("/user/Address?") Calll<AddressInfo> getAddress();POST:
/** * 上傳畫作 * @param content 圖集描述 * @param atk token值 * @param file 檔案 */ @Multipart @POST("/user/uploadPicture?")
Call<BaseResponse> upLoadPaint(@Part("content")String content, @Part("t")String atk,@Part("upfile") RequestBody body); 大致的升級過程算是完成了
接下來講講有什麼坑:
1.純粹使用retrofit介面返回不能是void ,而是相對應了Call<T>,介面的實現不在是直接使用Call回撥,而是用getAddress().enqueue(new CallBack)
這裡面的變動有點大,如果沒做好回撥函式的封裝,那升級的工作量就有點大了,這樣返回一個call可以用於取消請求。
2.在Retrofit 1.9中,如果獲取的 response 不能背解析成定義好的物件,則會呼叫failure。但是在Retrofit 2.0中,不管 response 是否能被解析。onResponse總是會被呼叫。但是在結果不能被解析的情況下,response.body()會返回null。別忘了處理這種情況。
如果response存在什麼問題,比如404什麼的,onResponse也會被呼叫。你可以從response.errorBody().string()中獲取錯誤資訊的主體。
3.retrofit2.0去掉了一些類:RetrofitError,TypeFile MultipartTypedOutput,如果在1.9中用到,升級的時候需要注意 [email protected]註解在1.9的時候使用方式:@Path(value="url", encode=false) String url
2.0時會導致encoded失效,此時推薦使用@Url動態替換url地址
@Multipart @POST Call<String> upload(@Url String url, @PartMap Map<String, RequestBody> params);5.多圖片上次的坑:MultipartTypedOutput,以及TypeFile在2.0之後被去除了
1.9的多圖片上傳方式:
/** * @param multipartTypedOutput 多個引數載入 */ @POST("/user/applyPainting?") void request2BePaint(@Body MultipartTypedOutput multipartTypedOutput,Callback<BaseResponse> callback);multipartTypedOutput組裝:
MultipartTypedOutput multipartTypedOutput = new MultipartTypedOutput(); multipartTypedOutput.addPart("t",new TypedString(painter.atk)); multipartTypedOutput.addPart("content",new TypedString(painter.content));for (int i=0;i<painter.fileImages.length;i++){ multipartTypedOutput.addPart("upfile["+i+"]",new TypedFile("image/jpeg", new File(painter.fileImages[i]))); }相對於簡單些,而到2.0之後就感覺很繁瑣
/** * 上傳檔案*/ @Multipart @POST Call<String> upload(@Url String url, @PartMap Map<String, RequestBody> params);組裝map以及RequestBody
RequestBody requestFile = null; Map<String, RequestBody> photos = new HashMap<>();for (int i = 0; i < formFiles.size(); i++) { //生成臨時壓縮圖片檔案 final File tempFile = FileUtils.createFile(AppConfig.MAIN_DIR_IMG, "IMG_TEMP_" + System.currentTimeMillis() + ".jpg"); Bitmap bitmap = PhotoUtils.compressBitmap(formFiles.get(i).getFile().getPath()); FileOutputStream fos = new FileOutputStream(tempFile); bitmap.compress(Bitmap.CompressFormat.JPEG, quality, fos); requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), tempFile); photos.put("AttachmentKey"+i+"\"; filename=\""+keys.get(i),requestFile);}以上就是我升級的過程,如有問題和錯誤請留言
相關推薦
升級okhttp3.0+和retrofit2.0+的過程以及遇到的坑
包名變化 okhttp3.0之前是:com.squareup.okhttp.*, 而到3.0之後變成:okhttp3.* retrofit2.0之前:retrofit.* retrofit2.0之後:retrofit2.* 都在末尾增加了版本號,顯示的更專業,但是這也給
Retrofit2.0和RxJava2.0的簡單封裝
一、首先新增專案依賴: implementation "com.squareup.okhttp3:logging-interceptor:$var.loggingInterceptor"
升級到Xcode8和ios10.0的時候呼叫相機崩潰
所以需要增加相簿:Privacy - Photo Library Usage Description允許此許可權才能儲存圖片 要錄製視訊的一定要加上(麥克風:Privacy - Microphone Usage Description)不然會崩的麥克風:Privacy - Microphone Usag
vue2.0和vue1.0路由對比以及腳手架初始路由分析
2.0新版本路由相比1.0在使用上做了一些改動,但核心思想並未改變,接下來稍作分析和對比,使用路由之前都需要引入vue-router.js檔案 一、兩個路由版本的初步分析 1.0 .js /*1.建立根元件 必須得要有一個根元件*/
Android6.0和7.0上遇到的坑以及解決方法
android系統的版本已經更新到了8.0了。根據統計版本的分佈已經從過去的2.x推進到4.x以上了。所以開發中已經幾乎可以不考慮2.x等版本了。 然後像6.0以上的份額也越來越多。所以開發中是有必要考慮6.0以上版本的。 現在比較新的版本中,6.0(API
django1.0和django2.0的基於正則表達式的url區別
正則 url django1.0 django2.0django1.0和django2.0的基於正則表達式的url區別
hdfs1.0和2.0復習
sla 系統配置 一致性 slaves 負責 們的 -m 檢測 hadoop2.0 1、Namenode元數據兩種映射:(1)文件名 -> block數據塊的映射(2)block數據塊 -> datanode節點地址的映射細節:(1)是持久化到NN的磁盤的(fs
Shader-AlphaTest(1.0和2.0)
所謂Alpha測試,就是指測試畫素點的a值,只有當該畫素點的a值符合要求時,才渲染該畫素,否則不渲染該畫素. 首先來看1.0版本: Shader "Custom/AlphaTest" { Properties { _MainTex ("Texture", 2D) = "white
VUE CLI 3.0和2.0的引入模組的一些改變
1.引入模組一定要加.vue 剛剛接觸vue cli 3.0 自己開發中引入模組遇到一些問題。 因為2.0中 引入模組的字尾可以不用.vue.字尾 在3.0中就會出現 下圖的 錯誤 提示你 未找到模組。 加了.vue字尾之後模組之後. 再次執行 npm run s
vue3.0和2.0的區別及專案的搭建
3.0 新加入了 TypeScript 以及 PWA 的支援 部分命令發生了變化: 下載安裝 npm install -g [email protected] 刪除了vue list 建立專案&n
Android camera framework7.0和6.0 主要差異
目前差異主要體現在介面封裝和程序分離方面。 1.程式碼結構 1).android6.0程式碼 目前Android6.0的程式碼,本地沒有原始碼,這裡就拿伺服器上版本了。可以發現在Android6.0上,介面都是在native層以原始碼方式實現了。由於以I開頭的檔案都具有b
selenium 1.0、selenium2.0和selenium3.0區別
selenium 1.0 RC幾個核心組成部分: RC Server - jar ,主要負責跟瀏覽器打交道 RC Client -jar,一系列jar包,主要用來寫測試用例 RC core -javascript ,由RC Server注入到瀏覽器的selenium 核心主要操作控制元件 這裡RC的
OpenCV中Mat和IplImage之間的相互裝換(OpenCV2.0和OpenCV3.0)
Mat是OpenCV和C++介面的矩陣類,IplImage是OpenCV和C語言介面的結構體。 Mat讀取顯示用的是imread、imshow等,IplImage讀取顯示用的是cvLoadImage()、cvShowImage()。 有時候會涉及到兩者之間的轉換,下面詳細見介紹一下兩者之
Android App相容8.0和9.0
Android在8.0限制了後臺服務這些,啟動後臺服務需要設定通知欄,使服務變成前臺服務。但是在9.0上,就會出現Permission Denial: startForeground requires android.permission.FOREGROUND_SERVICE。 解決辦法
android8.0和9.0適配的一些問題
1.懸浮窗windowmanager許可權問題 需要跳轉到對應的系統許可權管理處讓使用者自己勾選 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { // 進入設定系統應用
javaSE (三十四)File類和遞迴練習(統計資料夾大小、拷貝資料夾、層級列印資料夾、斐波拉契數列、獲取1000階乘全部0和尾部0數目、約瑟夫環)
1、統計資料夾大小: 思路: 套用之前已經做過的,鍵入一個路徑,若有效則封裝成File類 初始化計數器len, 若資料夾下是檔案,則記錄檔案.length() 若資料夾下是資料夾,遞迴 輸出len 注:遞迴也可以刪除資料夾,但是一定要先刪除裡
0.0.0.0 和127.0.0.1
127.0.0.1:是個(特殊的)IP地址,往往被分配給了loopback或僅區域網可以訪問的介面local-only interface 這是一個偽照的,假的,網路介面卡,其只能於同主機host內通訊 常用於:讓一個可以支援網路的程式,僅僅響應於同主機host內的客戶端
使用lifecycle時,1.0.0和1.0.3問題解決方法
將appcompat版本號改為27.0.2就行 implementation 'com.android.support:appcompat-v7:26.1.0' 我lifecycle修改後如下
C指標(*++argv)[0]和*++argv[0]的區別
*argv[]在linux系統中是輸入引數的集合,其中argv[0]指向呼叫的程式名稱,後面才是使用者輸入的引數; 那 ( *++argv)[0]和*++argv[0]表達的是什麼意思呢? 其實他們有自己特定的意義。 先對他們進行分析,根據結合性,[]的優先順序要大於*和++, *和++
Camera1.0和Camear2.0的區別
1. Camera2是通過系統服務拿到CameraManager來管理camera裝置物件,camera的一次預覽、拍照都是向請求會話(CaptureSession.StateCallback,攝像頭開啟時由相機裝置的輸出surface組成)傳送一次請求(CaptureRequest.Builder)。需