Retrofit2.0 網絡請求框架
隨着Google對HttpClient 摒棄,和Volley的逐漸沒落,OkHttp開始異軍突起,而Retrofit則對okHttp進行了強制依賴。
Retrofit是由Square公司出品的針對於Android和Java的類型安全的Http客戶端,
如果看源碼會發現其實質上就是對okHttp的封裝,使用面向接口的方式進行網絡請求,利用動態生成的代理類封裝了網絡接口請求的底層,
其將請求返回javaBean,對網絡認證 REST API進行了很好對支持此,使用Retrofit將會極大的提高我們應用的網絡體驗。
retrofit註解:
方法註解,包含@GET、@POST、@PUT、@DELETE、@PATH、@HEAD、@OPTIONS、@HTTP。
標記註解,包含@FormUrlEncoded、@Multipart、@Streaming。
參數註解,包含@Query,@QueryMap、@Body、@Field,@FieldMap、@Part,@PartMap。
其他註解,@Path、@Header,@Headers、@Url
幾個特殊的註解
@HTTP:可以替代其他方法的任意一種
/**
* method 表示請的方法,不區分大小寫
* path表示路徑
* hasBody表示是否有請求體
*/
@HTTP(method = "get", path = "users/{user}", hasBody = false)
Call<ResponseBody> getFirstBlog(@Path("user") String user);
@Url:使用全路徑複寫baseUrl,適用於非統一baseUrl的場景。
@GET
Call<ResponseBody> v3(@Url String url);
@Streaming:用於下載大文件
@Streaming
@GET
Call<ResponseBody> downloadFileWithDynamicUrlAsync(@Url String fileUrl);
ResponseBody body = response.body();
long fileSize = body.contentLength();
InputStream inputStream = body.byteStream();
常用註解
@Path:URL佔位符,用於替換和動態更新,相應的參數必須使用相同的字符串被@Path進行註釋
@Query,@QueryMap:查詢參數,用於GET查詢,需要注意的是@QueryMap可以約定是否需要encode
Call<List<News>> getNews((@QueryMap(encoded=true) Map<String, String> options);
@Body:用於POST請求體,將實例對象根據轉換方式轉換爲對應的json字符串參數,這個轉化方式是GsonConverterFactory定義的。
@POST("add") Call<List<User>> addUser(@Body User user);
- @Field,@FieldMap:Post方式傳遞簡單的鍵值對,需要添加@FormUrlEncoded表示表單提交 Content-Type:application/x-www-form-urlencoded
@FormUrlEncoded @POST("user/edit") Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
@Part,@PartMap:用於POST文件上傳其中@Part MultipartBody.Part代表文件,@Part(“key”) RequestBody代表參數需要添加@Multipart表示支持文件上傳的表單,Content- Type:multipart/form-data
參考:http://www.jianshu.com/p/3e13e5d34531
Rxjava
RxJava 在 GitHub 主頁上的自我介紹是 “a library for composing asynchronous and event-based programs using observable sequences for the Java VM”(一個在 Java VM 上使用可觀測的序列來組成異步的、基於事件的程序的庫)。這就是 RxJava ,概括得非常精準。
然而,對於初學者來說,這太難看懂了。因爲它是一個『總結』,而初學者更需要一個『引言』。
其實, RxJava 的本質可以壓縮爲異步這一個詞。說到根上,它就是一個實現異步操作的庫,而別的定語都是基於這之上的。
優點:
1. 簡潔
RxJava 的優勢也是簡潔,但它的簡潔的與衆不同之處在於,隨着程序邏輯變得越來越複雜,它依然能夠保持簡潔。
Observable.from(folders)
.flatMap(new Func1<File, Observable<File>>() {
@Override
public Observable<File> call(File file) {
return Observable.from(file.listFiles());
}
})
.filter(new Func1<File, Boolean>() {
@Override
public Boolean call(File file) {
return file.getName().endsWith(".png");
}
})
.map(new Func1<File, Bitmap>() {
@Override
public Bitmap call(File file) {
return getBitmapFromFile(file);
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Bitmap>() {
@Override
public void call(Bitmap bitmap) {
imageCollectorView.addImage(bitmap);
}
});
Observables 事件源
Observable可以是:數據庫查詢;屏幕點擊事件;網絡請求
Subscribers 觀察者
Subscribe可以是:顯示查詢結果;響應點擊事件;顯示請求結果
Map操作符
把一個事件轉換爲另一個事件(將最簡單的數據傳遞給Subscriber對象)
改變併發出新的數據類型的Observable對象
Dagger2
Dagger2是Dagger1的分支,由谷歌公司接手開發,目前的版本是2.0。Dagger2是受到AutoValue項目的啓發。 剛開始,Dagger2解決問題的基本思想是:利用生成和寫的代碼混合達到看似所有的產
生和提供依賴的代碼都是手寫的樣子。
依賴注入(Dependency Injection簡稱DI)
依賴注入:就是目標類(目標類需要進行依賴初始化的類,下面都會用目標類一詞來指代)中所依賴的其他的類的初始化過程,不是通過手動編碼的方式創建,而是通過技術手段可以把其他的類的已經初始化好的實例自動注入到目標類中。
java中註解(Annotation)
Module:提供依賴對象 eg:context,rest api
1. 在類上加上@Module
2. 在method上加上@provides
3. Modules可拆分成多個Module組合在一起
Module其實是一個簡單工廠模式,Module裏面的方法基本都是創建類實例的方法。
inject :需要依賴對象的地方
1. constructor injection (構造方法注入):表示參數要 dependency,這些參數可以被使用在 private或final的字段
2. Method injection:表示參數要 dependency,注入發生在對象被完全建立之後
3. Filed injection :屬性注入
Component:
連接Module和injection,現在是一個注入器,就像注射器一樣,Component會把目標類依賴的實例注入到目標類中,來初始化目標類中的依賴。
Dagger2 好處:
1、依賴的注入和配置獨立於組件之外,注入的對象在一個獨立、不耦合的地方初始化,這樣在改變注入對象時,我們只需要修改對象的實現方法,而不用大改代碼庫。
2、依賴可以注入到一個組件中:我們可以注入這些依賴的模擬實現,這樣使得測試更加簡單。
3、app中的組件不需要知道有關實例創建和生命週期的任何事情,這些由我們的依賴注入框架管理的。
我覺得,dagger2這樣的依賴注入框架對MVP架構來說,是最好的解耦工具,可以進一步降低modle-view-presenter之間的耦合度。
所以,如果你的項目在使用MVP架構開發,強烈建議配合dagger2一起使用。
接下來,分解這張圖:
AppComponent: 生命週期跟Application一樣的組件。可注入到自定義的Application類中,@Singletion代表各個注入對象爲單例。
@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
Context context(); // 提供Applicaiton的Context
ThreadExecutor threadExecutor(); // 線程池
ApiService apiService(); // 所有Api請求的管理類
SpfManager spfManager(); // SharedPreference管理類
DBManager dbManager(); // 數據庫管理類
}
AppModule: 這裏提供了AppComponent裏的需要注入的對象
@Module
public class AppModule {
private final MyApplication application;
public AppModule(MyApplication application) {
this.application = application;
}
@Provides
@Singleton
Context provideApplicationContext() {
return application;
}
@Provides
@Singleton
ThreadExecutor provideThreadExecutor(JobExecutor jobExecutor) {
return jobExecutor;
}
@Provides
@Singleton
ApiService providesApiService(RetrofitManager retrofitManager) {
return retrofitManager.getService();
}
@Provides
@Singleton
SpfManager provideSpfManager() {
return new SpfManager(application);
}
@Provides
@Singleton
DBManager provideDBManager() {
return new DBManager(application);
}
}