編輯:關於Android編程
當前的網絡開源庫有許多,如volley,okhttp,retrofit等,這三個庫當前是比較火的,其中,okhttp和retrofit由square團隊開發。關於這三個庫的區別,請移步stackoverflow或者知乎查看。開發過程中選擇什麼樣的開源庫需要更具我們APP來做出選擇。我們選出stackoverflow中的一段話來看下。
上面說,需要與web service通信的時候,我們使用retrofit。百度百科 web service介紹,那麼我們見天就來了解下retrofit。
關於什麼是retrofit,官網文檔上們有一句話。A type-safe HTTP client for Android and Java。額,似乎什麼也看出去來,就知道是一個類型安全的http client庫。那麼什麼是類型安全呢?類型安全代碼指訪問被授權可以訪問的內存位置。例如,類型安全代碼不能從其他對象的私有字段讀取值。它只從定義完善的允許方式訪問類型才能讀取。類型安全的代碼具備定義良好的數據類型。更多內容百度百科-類型安全,關於這裡還引用上面知乎的一句話。
RESTful-百度百科
rest-百度百科
上面這麼多抽象的概念太抽象,我們不管他。我們只需要知道retrofit確實是個很好的開源庫就可以了。
開源庫是不錯,但是,你文檔能不能寫的詳細點。入門就是個大老虎。怎麼說呢,文檔給出的代碼精辟,但是不能運行。那麼,我們來看看具體的,真正的入門步驟。
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
retrofit是中有用的okhttp,添加gson庫是為了將返回數據轉化為實體類。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxoMyBpZD0="2將http-api轉化為java接口">2.將http api轉化為java接口
以下稱這貨為http接口
比如我們想去這個網址上獲取json數據。https://api.github.com/users/Guolei1130
你們也可以將Guolei1130替換為你們自己的github。
public interface gitapi {
@GET("/users/{user}")
Call getFeed(@Path("user") String user);
}
這裡使用注解,@GET表示我們的請求方式是get請求,@GET(“STR”),標明這裡的請求地址為BASEURL+STR,{user},這裡會在後面被getFeed的user參數替換,最後就拼接成了最終的請求路徑。返回的數據室什麼呢。Call< gitmodel>,這裡返回的Call是用來讓我們執行請求的。需要注意的是:Call< T>表示返回體中的數據,我們看下上面那個網址的返回數據。
,很明顯是個json對象。
但是如果是返回數據為json數組的話我們就需要注意,這裡具體怎麼用還要根據返回數據以及我們的model來確定,倘若model對應json中的對象,便用Call< List< gitmodel>>,倘若對應json數組,用Call< gitmodel>。多的不說了,自己體會體會。
只需要將json對象的鍵值,編寫model對應的成員變量,在生成get set方法就好。
如圖:
Retrofit retrofit= new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
gitapi service = retrofit.create(gitapi.class);
Call model = service.getFeed("Guolei1130");
model.enqueue(new Callback() {
@Override
public void onResponse(Response 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請求(異步和同步,後面會說到)。別忘記添加權限。
好,到這裡入門老虎就被我們打死了。
我們既然知道了retrofit是通過注解將HTTP轉化為java接口,那麼我們就需要了解下都有哪些注解,該怎麼用。
GET, POST, PUT, DELETE, 和 HEAD,我們平常開發中經常用的也就get和post。關於HTTP請求方式,這裡就不再說了,網上有很多介紹HTTP協議的文章,都特別詳細。
我們知道get請求方式,參數是放在路徑當中的。看下圖的路徑。
,
是不是很長,不過沒關系,用retrofit一樣可以將這麼長的串拼接到路徑中,怎麼做呢?
這裡就用到了@Query(一個鍵值對)和@QueryMap(多對鍵值對)。
// 假設 baseurl = "http://baidu.com"
@GET("/s")
Call onekey(@Query("wd") String wdvalue);
上面代碼拼接出來的 = “http://baidu.com/s?wd=wdvalue“.
上面只是一個參數的時候,很多時候我們有許多參數,這個時候就需要我們使用@QueryMap 了
Call manykey(@QueryMap Map options);
上面的即可將多對鍵值對拼接到路徑當中。
我們知道post和get的區別當中有一點就是參數的位置,get放在url路徑當中,post放在請求體當中。
注意:前方高能,請仔細閱讀。前方高能,請仔細閱讀。前方高能,請仔細閱讀。下面我們模擬一個登錄,請求參數為用戶名和密碼,返回參數為我們的用戶名。
@POST("/index.php")
Call post(@Body User user);
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;
}
}
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 model = service.post(new User("guolei","123456"));
model.enqueue(new Callback() {
@Override
public void onResponse(Response response, Retrofit retrofit) {
Log.e(TAG, "onResponse: "+response.body().getDes());
}
@Override
public void onFailure(Throwable t) {
Log.e(TAG, "onFailure: "+t.getMessage() );
}
});
客戶端的代碼很簡單,在這裡就不做過多的解釋。重點在於客戶端和服務器之間的交互。媽蛋,坑死我了。官方文檔上有一句話是這樣說的。
意思就是請求體對象也會轉化為json,剛開始我們並不知道會轉化為json,我們還傻傻的在php代碼中$_POST[‘username’],試了幾次沒效果之後。果斷拿出工具來分析。
抓包神器Charles,關於如何使用我這裡不說,我這裡只說下如何設置android端代理。長按鏈接的網絡-》修改 網絡-》將代理設為手動,輸入IP和端口。如下圖:
。
接下來,我們利用抓包工具去看看服務器接受的數據。如下圖:
,
果然,是json數據,但是我擦,我們明顯感覺這種數據我們沒法通過$_POST來接收。怎麼辦呢,不著急,咱們可以通過如下代碼來接收。php完整代碼如下(ps:只是演示,沒幾行)
$des);
echo json_encode($arr);
恩,就這麼少,關於如下安裝php開發環境就不說了,so easy不是麼。最後,我們來看下效果圖:
什麼叫表單,我想大家都應該知道,表單中有很多元素,我們這裡也不例外。在html代碼中,我們經常通過form表單來提交。在上面的請求體中,我們明顯感覺那玩意十分貌似有點難用。不過沒關系,我們有表單。
還是和上個例子一樣。
@FormUrlEncoded
@POST("/index.php")
Call form(@Field("username") String username,@Field("password") String password);
Call model = service.form("guolei","123456");
看下輸出結果;
這個多part是什麼呢,就是將請求提分為多個部分,這個就沒啥好說了的。
我們知道http是有請求頭的,有些時候我們是需要填寫或者配置一下請求頭的,比如說,文件上傳,或者cookie保持。這裡的請求頭支持動態配置和靜態配置。
通過@Headers注解。如:下面這段是官方文檔上的。
@Headers({
"Accept: application/vnd.github.v3.full+json",
"User-Agent: Retrofit-Sample-App"
})
也來一段官方文檔上面的吧。
@GET("/user")
Call getUser(@Header("Authorization") String authorization)
這些都相對簡單的,沒啥好說的,事實上,在開發過程中需要我們配置請求頭的地方也不多。
這裡支持異步和同步。上面的例子中我們都是用的異步。那麼我們看下如何執行同步請求,也很簡單。
//同步請求
//model.execute().body().getLogin();
-dontwarn retrofit.**
-keep class retrofit.** { *; }
-keepattributes Signature
-keepattributes Exceptions
在拋物線大大的RxJava入門當中,我們知道了retrofit和rxjava可以結合使用,那麼我們現在便來看看如何使用。
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'
}
@FormUrlEncoded
@POST("/index.php")
public Observable rxpost(@Field("username") String username,@Field("password") String password);
Retrofit retrofit= new Retrofit.Builder()
// .baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.baseUrl("http://192.168.1.214")
.build();
gitapi service = retrofit.create(gitapi.class);
Observable observable = service.rxpost("quanshijie", "123456");
observable.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.newThread())
.subscribe(new Action1() {
@Override
public void call(Des des) {
Log.e(TAG, "call: " + des.getDes().toString());
mText.setText(des.getDes().toString());
}
}, new Action1() {
@Override
public void call(Throwable throwable) {
Log.e(TAG, "call: " + throwable.getLocalizedMessage());
}
});
在這裡我們要做好線程調度,現在網絡上那些坑爹的代碼,少一行代碼,把我坑了好長時間。喵了個咪的。最後看下效果圖。
到這裡,還差我們網絡請求的其他需求,比如說文件上傳下載,cookie保持,https協議支持等。在okhttp中,這些東西都可以,retrofit作為okhttp的兄弟,我想也不會太差,還得繼續學習啊。
不過,在查了一些資料之後,我們知道,網絡庫的選擇要根據需求,一個很大的項目中用一個網絡庫很顯然是不可能的。那麼,okhttp+retrofit+圖片緩存庫+rxjava會不會成為日後開發的主流呢。還是期待吧。
本博文是《第一行代碼 Android》的讀書筆記/摘錄。一、Content Provider簡介內容提供器(Content Provider)主要用於在不同的應用程序之間
過度繪制(Overdraw)是指在一幀的時間內像素被繪制了多次;理論上一個像素每次只繪制一次是最優的,但是由於層疊的布局導致一些像素會被多次繪制,而每次繪制都會對應到CP
前言之前因為項目需求,其中使用到了圖片的單擊顯示取消,圖片平移縮放功能,昨天突然想再加上圖片的旋轉功能,在網上看了很多相關的例子,可是沒看到能同時實現我想要的功能的。需求
1、 題外話 相信大家對LayoutInflate都不陌生,特別在ListView的Adapter的getView方法中基本都會出現,使用