<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ### 前言 當前的網絡開源庫有許多,如volley,okhttp,retrofit等,這三個庫當前是比較火的,其中,okhttp和retrofit由square團隊開發。關于這三個庫的區別,請移步[stackoverflow](http://stackoverflow.com/questions/16902716/comparison-of-android-networking-libraries-okhttp-retrofit-volley/)或者[知乎](http://www.zhihu.com/question/35189851)查看。開發過程中選擇什么樣的開源庫需要更具我們APP來做出選擇。我們選出stackoverflow中的一段話來看下。 ![](https://box.kancloud.cn/2016-04-08_57076806beecb.jpg "") 上面說,需要與web service通信的時候,我們使用retrofit。[百度百科 web service介紹](http://baike.baidu.com/link?url=FeGwtLhZW7pjuwc-o8gavLwVe6LRnC4tGK-JAw42uHD6GbwI7ex7NN0Ac3Q17NYnFhDBxHhXMANQp3mjLpCpyq),那么我們見天就來了解下retrofit。 ### 什么是retrofit 關于什么是retrofit,[官網文檔](http://square.github.io/retrofit/)上們有一句話。A type-safe HTTP client for Android and Java。額,似乎什么也看出去來,就知道是一個類型安全的http client庫。那么什么是類型安全呢?類型安全代碼指訪問被授權可以訪問的內存位置。例如,類型安全代碼不能從其他對象的私有字段讀取值。它只從定義完善的允許方式訪問類型才能讀取。類型安全的代碼具備定義良好的數據類型。更多內容[百度百科-類型安全](http://baike.baidu.com/link?url=LDmTGCvQfcX8SZB8DZb9GrHK-9uoqf3CadgGjNGjZPVZCIDEVO2uhgDBb4GIB8ktqms3HFLGjO9YVE8H__JHMq),關于這里還引用上面知乎的一句話。 ![](https://box.kancloud.cn/2016-04-08_57076806dd9fe.jpg "") [RESTful-百度百科](http://baike.baidu.com/link?url=07gpSp66HaU7PDIcsUpY7U6wV8ic3zzuL0QrElchvTqHjk4lTILGotJO3BNk_OOc2V-Bn1gjLQ_ay70lg_dHF_) [rest-百度百科](http://baike.baidu.com/link?url=5FvkIdS0cA_BIKKGhCEb6t8rNQgClAGxx1w6Mwnt4oEUAlvDKbWJmi5GZArR8cUapol07jimkCqF1wQVmYXCYgkOl9DWoWjovULf8SN78AO) 上面這么多抽象的概念太抽象,我們不管他。我們只需要知道retrofit確實是個很好的開源庫就可以了。 ### 入門打老虎 開源庫是不錯,但是,你文檔能不能寫的詳細點。入門就是個大老虎。怎么說呢,文檔給出的代碼精辟,但是不能運行。那么,我們來看看具體的,真正的入門步驟。 ### 1.在gradle腳本中添加 ~~~ compile 'com.squareup.retrofit:retrofit:2.0.0-beta2' compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2' ~~~ ![](https://box.kancloud.cn/2016-04-08_57076807000c9.jpg "") retrofit是中有用的okhttp,添加gson庫是為了將返回數據轉化為實體類。 ### 2.將http api轉化為java接口 以下稱這貨為http接口 比如我們想去這個網址上獲取json數據。[https://api.github.com/users/Guolei1130](https://api.github.com/users/Guolei1130) 你們也可以將Guolei1130替換為你們自己的github。 ~~~ public interface gitapi { @GET("/users/{user}") Call<gitmodel> getFeed(@Path("user") String user); } ~~~ 這里使用注解,@GET表示我們的請求方式是get請求,@GET(“STR”),標明這里的請求地址為BASEURL+STR,{user},這里會在后面被getFeed的user參數替換,最后就拼接成了最終的請求路徑。返回的數據室什么呢。Call< gitmodel>,這里返回的Call是用來讓我們執行請求的。需要注意的是:Call< T>表示返回體中的數據,我們看下上面那個網址的返回數據。 ![](https://box.kancloud.cn/2016-04-08_57076807132be.jpg "") ,很明顯是個json對象。 但是如果是返回數據為json數組的話我們就需要注意,這里具體怎么用還要根據返回數據以及我們的model來確定,倘若model對應json中的對象,便用Call< List< gitmodel>>,倘若對應json數組,用Call< gitmodel>。多的不說了,自己體會體會。 ### 3.model的編寫 只需要將json對象的鍵值,編寫model對應的成員變量,在生成get set方法就好。 如圖: ![](https://box.kancloud.cn/2016-04-08_570768073226b.jpg "") ### 4.執行請求 ~~~ Retrofit retrofit= new Retrofit.Builder() .baseUrl("https://api.github.com") .addConverterFactory(GsonConverterFactory.create()) .build(); gitapi service = retrofit.create(gitapi.class); Call<gitmodel> model = service.getFeed("Guolei1130"); model.enqueue(new Callback<gitmodel>() { @Override public void onResponse(Response<gitmodel> response, Retrofit retrofit) { Log.e(TAG, "onResponse: "+response.body().getLogin() ); } @Override public void onFailure(Throwable t) { Log.e(TAG, "onFailure: " + t.getMessage()); } }); ~~~ 這里我們先構造Retrofit對象,由于我們將返回的json數據轉化成了model對象,所以在構造Retrofit對象的時候,通過addConverterFactory來添加轉化器來完成數據轉化。 然后利用http接口的方法生成Call對象,最后用Call對象來執行http請求(異步和同步,后面會說到)。別忘記添加權限。 ![](https://box.kancloud.cn/2016-04-08_570768075263f.jpg "") 好,到這里入門老虎就被我們打死了。 ### 注解爽歪歪 我們既然知道了retrofit是通過注解將HTTP轉化為java接口,那么我們就需要了解下都有哪些注解,該怎么用。 ![](https://box.kancloud.cn/2016-04-08_5707680764571.jpg "") ### 請求方式 GET, POST, PUT, DELETE, 和 HEAD,我們平常開發中經常用的也就get和post。關于HTTP請求方式,這里就不再說了,網上有很多介紹HTTP協議的文章,都特別詳細。 我們知道get請求方式,參數是放在路徑當中的。看下圖的路徑。 ![](https://box.kancloud.cn/2016-04-08_5707680779106.jpg "") , 是不是很長,不過沒關系,用retrofit一樣可以將這么長的串拼接到路徑中,怎么做呢? 這里就用到了@Query(一個鍵值對)和@QueryMap(多對鍵值對)。 ~~~ // 假設 baseurl = "http://baidu.com" @GET("/s") Call<gitmodel> onekey(@Query("wd") String wdvalue); ~~~ 上面代碼拼接出來的 = “[http://baidu.com/s?wd=wdvalue](http://baidu.com/s?wd=wdvalue)“. 上面只是一個參數的時候,很多時候我們有許多參數,這個時候就需要我們使用@QueryMap 了 ~~~ Call<gitmodel> manykey(@QueryMap Map<String, String> options); ~~~ 上面的即可將多對鍵值對拼接到路徑當中。 ### 請求體 我們知道post和get的區別當中有一點就是參數的位置,get放在url路徑當中,post放在請求體當中。 注意:前方高能,請仔細閱讀。前方高能,請仔細閱讀。前方高能,請仔細閱讀。下面我們模擬一個登錄,請求參數為用戶名和密碼,返回參數為我們的用戶名。 #### 1.轉化為接口 ~~~ @POST("/index.php") Call<Des> post(@Body User user); ~~~ #### 2.編寫User和Des,用 來轉化數據 ~~~ public class Des { public String des; public String getDes() { return des; } public void setDes(String des) { this.des = des; } } ~~~ ~~~ public class User { public String username; public String password; public User(String username,String password){ this.username = username; this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } } ~~~ #### 3.發送請求 ~~~ Retrofit retrofit= new Retrofit.Builder() // .baseUrl("https://api.github.com") .baseUrl("http://192.168.1.214") .addConverterFactory(GsonConverterFactory.create()) .build(); gitapi service = retrofit.create(gitapi.class); Call<Des> model = service.post(new User("guolei","123456")); model.enqueue(new Callback<Des>() { @Override public void onResponse(Response<Des> response, Retrofit retrofit) { Log.e(TAG, "onResponse: "+response.body().getDes()); } @Override public void onFailure(Throwable t) { Log.e(TAG, "onFailure: "+t.getMessage() ); } }); ~~~ 客戶端的代碼很簡單,在這里就不做過多的解釋。重點在于客戶端和服務器之間的交互。媽蛋,坑死我了。官方文檔上有一句話是這樣說的。 ![](https://box.kancloud.cn/2016-04-08_570768078cdce.jpg "") 意思就是請求體對象也會轉化為json,剛開始我們并不知道會轉化為json,我們還傻傻的在php代碼中$_POST[‘username’],試了幾次沒效果之后。果斷拿出工具來分析。 [抓包神器Charles](http://pan.baidu.com/s/1c08brfq),關于如何使用我這里不說,我這里只說下如何設置android端代理。長按鏈接的網絡-》修改 網絡-》將代理設為手動,輸入IP和端口。如下圖: ![](https://box.kancloud.cn/2016-04-08_570768079fe76.jpg "") 。 接下來,我們利用抓包工具去看看服務器接受的數據。如下圖: ![](https://box.kancloud.cn/2016-04-08_57076807b9e3b.jpg "") , 果然,是json數據,但是我擦,我們明顯感覺這種數據我們沒法通過$_POST來接收。怎么辦呢,不著急,咱們可以通過如下代碼來接收。php完整代碼如下(ps:只是演示,沒幾行) ~~~ <?php $var=file_get_contents("php://input"); $obj= json_decode($var,true); $des = $obj['username']; $arr = array("des"=>$des); echo json_encode($arr); ~~~ 恩,就這么少,關于如下安裝php開發環境就不說了,so easy不是么。最后,我們來看下效果圖: ![](https://box.kancloud.cn/2016-04-08_57076807cc10b.jpg "") ### 表單編碼和多part 什么叫表單,我想大家都應該知道,表單中有很多元素,我們這里也不例外。在html代碼中,我們經常通過form表單來提交。在上面的請求體中,我們明顯感覺那玩意十分貌似有點難用。不過沒關系,我們有表單。 還是和上個例子一樣。 ~~~ @FormUrlEncoded @POST("/index.php") Call<Des> form(@Field("username") String username,@Field("password") String password); ~~~ ~~~ Call<Des> model = service.form("guolei","123456"); ~~~ 看下輸出結果; ![](https://box.kancloud.cn/2016-04-08_57076807e445e.jpg "") 這個多part是什么呢,就是將請求提分為多個部分,這個就沒啥好說了的。 ### 請求頭 我們知道http是有請求頭的,有些時候我們是需要填寫或者配置一下請求頭的,比如說,文件上傳,或者cookie保持。這里的請求頭支持動態配置和靜態配置。 #### 1.靜態配置 通過@Headers注解。如:下面這段是官方文檔上的。 ~~~ @Headers({ "Accept: application/vnd.github.v3.full+json", "User-Agent: Retrofit-Sample-App" }) ~~~ #### 2.動態配置 也來一段官方文檔上面的吧。 ~~~ @GET("/user") Call<User> getUser(@Header("Authorization") String authorization) ~~~ 這些都相對簡單的,沒啥好說的,事實上,在開發過程中需要我們配置請求頭的地方也不多。 ### 執行方式 這里支持異步和同步。上面的例子中我們都是用的異步。那么我們看下如何執行同步請求,也很簡單。 ~~~ //同步請求 //model.execute().body().getLogin(); ~~~ ### 混淆代碼 ~~~ -dontwarn retrofit.** -keep class retrofit.** { *; } -keepattributes Signature -keepattributes Exceptions ~~~ ### retrofit+rxjava 在拋物線大大的RxJava入門當中,我們知道了retrofit和rxjava可以結合使用,那么我們現在便來看看如何使用。 ### 1.添加 ~~~ dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.0.1' compile 'com.squareup.retrofit:retrofit:2.0.0-beta2' compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2' compile 'io.reactivex:rxjava:1.0.16' compile 'io.reactivex:rxandroid:1.0.1' compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta2' } ~~~ ### 2.http api接口 ~~~ @FormUrlEncoded @POST("/index.php") public Observable<Des> rxpost(@Field("username") String username,@Field("password") String password); ~~~ ### 3.在retrofit中添加RxJavaCallAdapterFactory ~~~ Retrofit retrofit= new Retrofit.Builder() // .baseUrl("https://api.github.com") .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .baseUrl("http://192.168.1.214") .build(); ~~~ ### 4.執行 ~~~ gitapi service = retrofit.create(gitapi.class); Observable<Des> observable = service.rxpost("quanshijie", "123456"); observable.observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.newThread()) .subscribe(new Action1<Des>() { @Override public void call(Des des) { Log.e(TAG, "call: " + des.getDes().toString()); mText.setText(des.getDes().toString()); } }, new Action1<Throwable>() { @Override public void call(Throwable throwable) { Log.e(TAG, "call: " + throwable.getLocalizedMessage()); } }); ~~~ 在這里我們要做好線程調度,現在網絡上那些坑爹的代碼,少一行代碼,把我坑了好長時間。喵了個咪的。最后看下效果圖。 ![](https://box.kancloud.cn/2016-04-08_570768080237c.jpg "") ### 總結 到這里,還差我們網絡請求的其他需求,比如說文件上傳下載,cookie保持,https協議支持等。在okhttp中,這些東西都可以,retrofit作為okhttp的兄弟,我想也不會太差,還得繼續學習啊。 不過,在查了一些資料之后,我們知道,網絡庫的選擇要根據需求,一個很大的項目中用一個網絡庫很顯然是不可能的。那么,okhttp+retrofit+圖片緩存庫+rxjava會不會成為日后開發的主流呢。還是期待吧。 好累啊,到現在飯都沒吃。retrofit的坑還是有的。我估計剩下的三點地方坑更大,不扯了,收工。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看