成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

鴻蒙系統的網絡請求框架—蒹葭

系統
文章由鴻蒙社區產出,想要了解更多內容請前往:51CTO和華為官方戰略合作共建的鴻蒙技術社區https://harmonyos.51cto.com

[[397656]]

想了解更多內容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術社區

https://harmonyos.51cto.com

一、前言

蒹葭(JianJia)是一款鴻蒙系統上的網絡請求框架,其實就是將安卓的Retrofit移植到鴻蒙系統上,我將鴻蒙版的Retrofit命名為蒹葭(JianJia)。蒹葭不僅能實現Retrofit的功能,還會提供一些Retrofit沒有的功能。Retrofit不支持動態替換域名,國內的應用一般都是有多個域名的,蒹葭支持動態替換域名。

二、源碼

源碼

博客地址

要想讀懂源碼,需要具備以下技能。

  • 熟悉okhttp的常見用法 ;
  • 熟悉面向接口編程、反射、泛型、注解;
  • 熟悉構造者模式、適配器模式、工廠模式、策略模式、靜態代理、動態代理、責任鏈模式等設計模式。

三、混淆

如果項目開啟了混淆,請在proguard-rules.pro添加如下的代碼。關于混淆,可以查看鴻蒙代碼配置混淆

  1. -renamesourcefileattribute SourceFile 
  2. -keepattributes SourceFile,LineNumberTable 
  3. -dontwarn javax.annotation.** 
  4. -keepattributes Signature, InnerClasses, EnclosingMethod, Exceptions 
  5. # 蒹葭 
  6. -dontwarn poetry.jianjia.** 
  7. -keep class poetry.jianjia.** { *; } 
  8. -keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations 
  9. -keepclassmembers,allowshrinking,allowobfuscation interface * { 
  10.     @poetry.jianjia.http.* <methods>; 
  11.  
  12. # OkHttp3 
  13. -dontwarn okhttp3.logging.** 
  14. -keep class okhttp3.internal.**{*;} 
  15. -dontwarn okio.** 
  16.  
  17. # gson 
  18. -keep class sun.misc.Unsafe { *; } 
  19. -keep class com.google.gson.stream.** { *; } 
  20. -keepattributes *Annotation* 
  21. -keepclassmembers class * implements java.io.Serializable { 
  22.     static final long serialVersionUID; 
  23.     private static final java.io.ObjectStreamField[] serialPersistentFields; 
  24.     private void writeObject(java.io.ObjectOutputStream); 
  25.     private void readObject(java.io.ObjectInputStream); 
  26.     java.lang.Object writeReplace(); 
  27.     java.lang.Object readResolve(); 
  28. # 在我的示例代碼中,com.poetry.jianjia.bean這個包下面的類實現了Serialized接口, 
  29. # 實現了Serialized接口的類不能被混淆,請把com.poetry.jianjia.bean這個包名替換成你自己的包名 
  30. -keep class com.poetry.jianjia.bean.**{*;} 

 四、添加依賴

4、1 在項目根目錄下的build.gradle文件中添加mavenCentral()倉庫,打開項目根目錄下的build.gradle文件,在build.gradle文件的repositories閉包下面添加mavenCentral()

  1. buildscript { 
  2.     repositories { 
  3.         // 添加maven中央倉庫 
  4.         mavenCentral() 
  5.         maven { 
  6.             url 'https://mirrors.huaweicloud.com/repository/maven/' 
  7.         } 
  8.         maven { 
  9.             url 'https://developer.huawei.com/repo/' 
  10.         } 
  11.         maven { 
  12.             url 'http://maven.aliyun.com/nexus/content/repositories/central/' 
  13.         } 
  14.         jcenter() 
  15.     } 
  16.     dependencies { 
  17.         classpath 'com.huawei.ohos:hap:2.4.2.5' 
  18.         classpath 'com.huawei.ohos:decctest:1.0.0.6' 
  19.     } 
  20.  
  21. allprojects { 
  22.     repositories { 
  23.         // 添加maven中央倉庫 
  24.         mavenCentral() 
  25.         maven { 
  26.             url 'https://mirrors.huaweicloud.com/repository/maven/' 
  27.         } 
  28.         maven { 
  29.             url 'https://developer.huawei.com/repo/' 
  30.         } 
  31.         maven { 
  32.             url 'http://maven.aliyun.com/nexus/content/repositories/central/' 
  33.         } 
  34.         jcenter() 
  35.     } 

 4、2 打開entry目錄下的build.gradle文件中,在build.gradle文件中的dependencies閉包下添加下面的依賴

  1. // 蒹葭的核心代碼 
  2. implementation 'io.gitee.zhongte:jianjia:1.0.0' 
  3. // 數據轉換器,數據轉換器使用gson來幫我們解析json,不需要我們手動解析json 
  4. implementation 'io.gitee.zhongte:converter-gson:1.0.0' 
  5. implementation "com.google.code.gson:gson:2.8.2" 
  6. // 日志攔截器,通過日志攔截器可以看到請求頭、請求體、響應頭、響應體 
  7. implementation 'com.squareup.okhttp3:logging-interceptor:3.7.0' 

 4、3 在配置文件中添加如下的權限

  1. ohos.permission.INTERNET 

五、具體用法,用法跟retrofit一樣

蒹葭提供了一系列的注解,在進行網絡請求的時候,就需要用到這些注解。

5、1 GET注解

創建接口,在方法里面使用GET注解,GET注解用于標識這是一個GET請求,方法的返回值是Call對象,泛型是ResponseBody,其實泛型也可以是具體的實體對象,這個后面再說。蒹葭如何完成網絡請求?使用構造者模式創建jianjia對象,baseUrl就是域名,在創建jianjia對象的時候就必須指定域名。調用create方法來生成接口的實例,調用wan.getBanner().enqueue來執行網絡請求,請求成功就會回調onResponse方法,請求失敗就會回調onFailure方法。

  1. public interface Wan { 
  2.   
  3.     @GET("banner/json"
  4.     Call<ResponseBody> getBanner(); 
  5.   
  6. JianJia jianJia = new JianJia.Builder() 
  7.         .baseUrl("https://www.wanandroid.com"
  8.         .build(); 
  9.   
  10. Wan wan = jianJia.create(Wan.class); 
  11. wan.getBanner().enqueue(new Callback<ResponseBody>() { 
  12.     @Override 
  13.     public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { 
  14.         try { 
  15.             String json = response.body().string(); 
  16.         } catch (IOException e) { 
  17.             e.printStackTrace(); 
  18.         } 
  19.     } 
  20.   
  21.     @Override 
  22.     public void onFailure(Call<ResponseBody> call, Throwable t) { 
  23.         LogUtils.info("yunfei", t.getMessage()); 
  24.     } 
  25. }); 

 5、2 BaseUrl注解

國內的應用一般都是有多個域名的,BaseUrl注解可以對某個接口設置單獨的域名。

  1. public interface Wan { 
  2.   
  3.     @BaseUrl("https://api.apiopen.top"
  4.     @GET("getJoke"
  5.     Call<ResponseBody> getJoke(@QueryMap Map<String, String> param); 
  6.       

 5、3 Path注解

Path注解在路徑中替換指定的參數值,定義下面的方法。可以看到我們定義了一個getArticle方法,方法接收一個page參數,并且我們的@GET注解中使用{page}聲明了訪問路徑,這里你可以把{page}當做占位符,而實際運行中會通過@Path("page")所標注的參數進行替換。

  1. public interface Wan { 
  2.   
  3.     @GET("article/list/{page}/json"
  4.     Call<ResponseBody> getArticle(@Path("page"int page); 
  5.   

 5、4 Query注解

Query注解用于給get請求添加請求參數,被Query注解修飾的參數類型可以是數組、集合、字符串等。

  1. public interface Wan { 
  2.   
  3.     @GET("wxarticle/list/405/1/json"
  4.     Call<ResponseBody> search(@Query("k") String k); 
  5.   
  6.     @GET("wxarticle/list/405/1/json"
  7.     Call<ResponseBody> search(@Query("k") String... k); 
  8.   
  9.     @GET("wxarticle/list/405/1/json"
  10.     Call<ResponseBody> search(@Query("k") List<String> k); 
  11.   

 5、5 QueryMap注解

QueryMap注解以map的形式添加查詢參數,被QueryMap注解修飾的參數類型必須是Map對象。

  1. public interface Wan { 
  2.   
  3.     @GET("wxarticle/list/405/1/json"
  4.     Call<ResponseBody> search(@QueryMap Map<String, String> param); 
  5.       

 5、6 SkipCallbackExecutor注解

在鴻蒙系統上,蒹葭默認會將服務端的響應回調到主線程,如果在方法上使用SkipCallbackExecutor注解,那就不會將服務端的結果回調到主線程。

  1. public interface Wan { 
  2.     @SkipCallbackExecutor 
  3.     @GET("wxarticle/list/405/1/json"
  4.     Call<ResponseBody> search(@QueryMap Map<String, String> param); 
  5.       

 5、7 FormUrlEncoded注解和Field注解

FormUrlEncoded注解用于發送一個表單請求,使用該注解必須在方法的參數添加Field注解,被Field注解修飾的參數類型可以是數組、集合、字符串等。

  1. public interface Wan { 
  2.     @POST("user/login"
  3.     @FormUrlEncoded 
  4.     Call<ResponseBody> login(@Field("username") String username, @Field("password") String password); 
  5.       

 5、8 FormUrlEncoded注解和FieldMap注解

有時候表單的參數會比較多,如果使用Field注解,方法的參數就會比較多,此時就可以使用FieldMap注解,FieldMap注解以鍵值對的形式發送一個表單請求。如果被FieldMap注解修飾的參數不是Map類型,就會拋異常。如果Map的鍵值對為空,也會拋異常。

  1. public interface Wan { 
  2.     @POST("user/login"
  3.     @FormUrlEncoded 
  4.     Call<ResponseBody> login(@FieldMap Map<String, String> map); 
  5.       

 5、9 Body注解

服務端會要求端上把json字符串作為請求體發給服務端。此時就可以使用Body注解定義的參數可以直接傳入一個實體類,內部會把該實體序列化并將序列化后的結果直接作為請求體發送出去。

如果被Body注解修飾的參數的類型是RequestBody對象,那調用者可以不添加數據轉換器,內部會使用默認的數據轉換器。

如果被Body注解修飾的參數的類型不是RequestBody對象,是一個具體的實體類,那調用者需要自定義一個類,并且繼承Converter.Factory。

  1. public interface Wan { 
  2.   
  3.     /** 
  4.      * 被Body注解修飾的參數的類型是RequestBody對象,那調用者可以不添加數據轉換器,內部會使用默認的數據轉換器 
  5.      * 
  6.      * @param body 
  7.      * @return 
  8.      */ 
  9.     @POST("user/register"
  10.     Call<ResponseBody> register(@Body RequestBody body); 
  11.   
  12.     /** 
  13.      * 被Body注解修飾的參數的類型不是RequestBody對象,是一個具體的實體類,那調用者需要自定義一個類,并且繼承Converter.Factory 
  14.      *  
  15.      * @param user 
  16.      * @return 
  17.      */ 
  18.     @POST("user/register"
  19.     Call<ResponseBody> register(@Body User user); 

 5、10 Url注解

Url注解用于添加接口的完整地址。在Retrofit里面,如果接口的域名與創建retrofit對象指定的域名不相同,那就會使用Url注解來解決問題。在蒹葭里面同樣可以使用Url注解來解決問題,但蒹葭還提供了BaseUrl來解決該問題。

  1. public interface Wan { 
  2.   
  3.     @GET() 
  4.     Call<ResponseBody> getArticle(@Url String url); 
  5.       

 5、11 Headers注解

Headers注解是作用于方法上的注解,用于添加一個或多個請求頭。

  1. public interface Wan { 
  2.   
  3.     @Headers("Cache-Control: max-age=640000"
  4.     @GET("/"
  5.     Call<ResponseBody> getArticle(@Url String url); 
  6.       
  7.     @Headers({ 
  8.      "X-Foo: Bar"
  9.      "X-Ping: Pong" 
  10.    }) 
  11.     @GET("/"
  12.     Call<ResponseBody> getArticle(@Url String url); 
  13.       

 5、12 Header注解

Header注解是作用于參數上的注解,用于添加請求頭。

  1. public interface Wan { 
  2.   
  3.     @GET() 
  4.    Call<ResponseBody> foo(@Header("Accept-Language") String lang); 
  5.       

 5、13 HeaderMap注解

HeaderMap注解是作用于參數上的注解,以map的形式添加請求頭,map中每一項的鍵和值都不能為空,否則會拋異常。

  1. public interface Wan { 
  2.   
  3.     @GET("/search"
  4.    Call<ResponseBody> list(@HeaderMap Map<String, String> headers); 
  5.       

 5、14 添加數據轉換器

之前我們在接口里面定義方法的時候,方法的返回值時Call對象,泛型是ResponseBody。在這種情況下,服務端返回給端上的數據就會在ResponseBody里面,端上需要手動解析json,將json解析成一個實體類。

其實,我們沒必要手動解析json,可以讓gson幫我們解析json。蒹葭支持添加數據轉換器,在創建對象的時候添加數據轉換器,也就是把gson添加進來。在onResponse方法里面就可以直接得到實體類對象了,gson幫我們把json解析成了一個實體對象。

首先在build.gradle文件添加數據轉換器的依賴。

  1. // 數據轉換器,數據轉換器使用gson來幫我們解析json,不需要我們手動解析json 
  2. implementation 'io.gitee.zhongte:converter-gson:1.0.0' 
  3. implementation "com.google.code.gson:gson:2.8.2" 

 在代碼中使用數據轉換器

  1. public interface Wan { 
  2.   
  3.     @GET("banner/json"
  4.     Call<Banner> getBanner(); 
  5.   
  6. JianJia jianJia = new JianJia.Builder() 
  7.         .baseUrl("https://www.wanandroid.com"
  8.         .addConverterFactory(GsonConverterFactory.create()) 
  9.         .build(); 
  10.   
  11. Wan wan = jianJia.create(Wan.class); 
  12. wan.getBanner().enqueue(new Callback<Banner>() { 
  13.     @Override 
  14.     public void onResponse(Call<Banner> call, Response<Banner> response) { 
  15.         try { 
  16.             if (response.isSuccessful()) { 
  17.                 // json已經被解析成banner對象了 
  18.                 Banner banner = response.body(); 
  19.             } 
  20.         } catch (IOException e) { 
  21.             e.printStackTrace(); 
  22.         } 
  23.     } 
  24.   
  25.     @Override 
  26.     public void onFailure(Call<Banner> call, Throwable t) { 
  27.         LogUtils.info("yunfei", t.getMessage()); 
  28.     } 
  29. }); 

 六、總結

本文介紹了蒹葭的用法,蒹葭的原理跟retrofit是一樣的,有興趣的同學可以去看下源碼。

想了解更多內容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術社區

https://harmonyos.51cto.com

 

責任編輯:jianghua 來源: 鴻蒙社區
相關推薦

2021-11-09 09:43:52

鴻蒙HarmonyOS應用

2018-05-03 19:14:23

iOS開發框架API

2020-11-11 11:56:05

HarmonyOS

2021-05-24 10:32:04

鴻蒙HarmonyOS應用

2022-08-25 21:46:51

網絡通訊應用開發

2020-10-23 09:47:19

HarmonyOSJS開發框架

2024-07-26 16:17:22

2022-02-28 15:44:05

鴻蒙系統鴻蒙API加載網絡圖片

2021-12-03 09:49:59

鴻蒙HarmonyOS應用

2021-04-15 09:18:57

鴻蒙HarmonyOS應用

2017-04-21 16:00:09

2019-03-28 11:00:37

前端網絡請求開發

2022-06-15 15:40:16

元宇宙

2021-11-03 09:33:51

網絡私有請求

2011-08-01 13:57:20

iPhone 網絡

2024-11-04 08:16:08

Go語言Web 框架

2023-04-12 07:35:33

2017-06-20 09:07:22

uvloopPython網絡框架

2016-12-20 14:20:05

Android網絡框架

2019-05-07 16:15:06

iOS系統系統通知庫通知消息
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲精品第一页 | 免费在线国产视频 | 欧美中文字幕一区二区 | 国产精品成人一区二区三区夜夜夜 | 欧美色人 | 精品久久国产老人久久综合 | 天天综合永久 | 久久久精品一区 | 日韩中文在线 | 亚洲性人人天天夜夜摸 | 免费黄色日本 | 久久最新精品 | 黄色网址在线免费播放 | 亚洲va国产日韩欧美精品色婷婷 | 黄a在线观看 | 综合国产在线 | 91精品久久久 | 成人一区二区三区 | 91看国产| 国产一区影院 | 国产99久久| 亚洲一区自拍 | 玖玖玖在线观看 | 精品综合久久久 | 欧美a级成人淫片免费看 | 在线欧美亚洲 | 国产精品99久久久久久大便 | 成人午夜精品 | 欧美久久一区二区三区 | 在线视频成人 | 九九爱这里只有精品 | 精品国产青草久久久久96 | 亚洲精品免费观看 | 中文字幕免费视频 | 久久99精品久久久久久青青日本 | 久久精品欧美一区二区三区不卡 | 狠狠久久综合 | 久久久久久久久久久国产 | 特级毛片爽www免费版 | 四虎影院在线观看av | 国产精品综合一区二区 |