RxVolley是一個基於Volley的網絡請求庫;同時支持RxJava;能夠選擇使用OKHttp替代默認的 HttpUrlConnection 作網絡請求;能夠選擇使用圖片加載功能(複用的網絡請求將有效減小apk體積);移除了原Volley的 HttpClient 相關 API ,可在 API23 環境編譯;內置了RxBus的實現,可有效替換掉EventBus等相關庫;
使用RxVolley,須要在你的build.gradle文件中加入
compile 'com.kymjs.rxvolley:rxvolley:1.0.7'
若是你還想使用OKhttp來替代默認的HttpUrlconnection,須要加入
compile 'com.kymjs.rxvolley:okhttp:1.0.7'
若是你想使用RxVolley的圖片加載功能(複用http模塊能夠有效減小apk大小),須要加入
compile 'com.kymjs.rxvolley:bitmapcore:1.0.7'
使用 RxVolley 作網絡請求java
//get請求簡潔版實現 RxVolley.get("http://www.kymjs.com/feed.xml", new HttpCallback() { @Override public void onSuccess(String t) { Loger.debug("請求到的數據:" + t); } }); //post請求簡潔版實現 HttpParams params = new HttpParams(); params.put("name", "kymjs"); params.put("age", 18); params.put("image", new File("path"))//文件上傳 RxVolley.post("http://kymjs.com/feed.xml", params, new HttpCallback() { @Override public void onSuccess(String t) { Loger.debug("請求到的數據:" + t); } });
//用戶登陸邏輯(HttpCallback中有不少重載方法,能夠選擇須要的實現) HttpParams params = new HttpParams(); params.put("name", "kymjs"); params.put("age", 18); params.put("password", "helloword"); RxVolley.post("http://kymjs.com/login", params, new HttpCallback() { @Override public void onSuccess(Map<String, String> headers, byte[] t) { Loger.debug("請求到的數據:" + new String(t)); // 獲取到的cookie Loger.debug("===" + headers.get("Set-Cookie")); } });
//向服務器傳遞cookie信息 HttpParams params = new HttpParams(); params.put("name", "kymjs"); params.put("age", 100); params.putHeaders("cookie", "your cookie"); RxVolley.post("http://kymjs.com/update", params, new HttpCallback() { @Override public void onSuccess(String t) { Loger.debug("請求到的數據:" + t); } });
比起 入門 章節講述的網絡請求,你可能但願有更多的需求android
HttpParams params = new HttpParams(); //同以前的設計,傳遞 http 請求頭能夠使用 putHeaders() params.putHeaders("cookie", "your cookie"); params.putHeaders("User-Agent", "rxvolley"); //傳遞 http 請求參數能夠使用 put() params.put("name", "kymjs"); params.put("age", "18"); //http請求的回調,內置了不少方法,詳細請查看源碼 //包括在異步響應的onSuccessInAsync():注不能作UI操做 //網絡請求成功時的回調onSuccess() //網絡請求失敗時的回調onFailure():例如無網絡,服務器異常等 HttpCallback callback = new HttpCallback(){ @Override public void onSuccessInAsync(byte[] t) { } @Override public void onSuccess(String t) { } @Override public void onFailure(int errorNo, String strMsg) { } } ProgressListener listener = new ProgressListener(){ /** * @param transferredBytes 進度 * @param totalSize 總量 */ @Override public void onProgress(long transferredBytes, long totalSize){ } } new RxVolley.Builder() .url("http://www.kymjs.com/rss.xml") //接口地址 //請求類型,若是不加,默認爲 GET 可選項: //POST/PUT/DELETE/HEAD/OPTIONS/TRACE/PATCH .httpMethod(RxVolley.Method.GET) //設置緩存時間: 默認是 get 請求 5 分鐘, post 請求不緩存 .cacheTime(6) //內容參數傳遞形式,若是不加,默認爲 FORM 表單提交,可選項 JSON 內容 .contentType(RxVolley.ContentType.FORM) .params(params) //上文建立的HttpParams請求參數集 //是否緩存,默認是 get 請求 5 緩存分鐘, post 請求不緩存 .shouldCache(true) .progressListener(listener) //上傳進度 .callback(callback) //響應回調 .encoding("UTF-8") //編碼格式,默認爲utf-8 .doTask(); //執行請求操做
RxVolley 支持返回一個 Observable 類型的數據,以下是 Result 類的原型
public class Result { public Map<String, String> header; public byte[] data; public Result(Map<String, String> header, byte[] data) { this.header = header; this.data = data; } }
執行一次請求,並返回 Observablegit
Observable<Result> observable = new RxVolley.Builder() .url("http://www.kymjs.com/rss.xml") //default GET or POST/PUT/DELETE/HEAD/OPTIONS/TRACE/PATCH .httpMethod(RxVolley.Method.POST) .cacheTime(6) //default: get 5min, post 0min .params(params) .contentType(RxVolley.ContentType.JSON) .getResult(); // 使用getResult()來返回RxJava數據類型 //當拿到 observable 對象後,你能夠設置你本身的 subscriber observable.subscribe(subscriber);
完整的使用示例
public class MainActivity extends AppCompatActivity { private Subscription subscription; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Observable<Result> observable = new RxVolley.Builder() .url("http://kymjs.com/feed.xml") .contentType(RxVolley.ContentType.FORM) .getResult(); subscription = observable .map(new Func1<Result, String>() { @Override public String call(Result result) { return new String(result.data); } }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<String>() { @Override public void call(String result) { Log.i("kymjs", "======網絡請求" + result); } }); } @Override protected void onDestroy() { super.onDestroy(); if (subscription != null && subscription.isUnsubscribed()) { subscription.unsubscribe(); } } }
也許你是 Volley 的重度使用者(就像我),那麼你必定是由於 Volley 自由的擴展性而愛上它的。
你能夠經過建立一個Request
RxVolley.Builder().setRequest(yourRequest).doTask();
去執行你的自定義 Request
一個典型自定義Request的示例:
/** * Form表單形式的Http請求 */ public class FormRequest extends Request<byte[]> { private final HttpParams mParams; public FormRequest(RequestConfig config, HttpParams params, HttpCallback callback) { super(config, callback); if (params == null) { params = new HttpParams(); } this.mParams = params; } @Override public String getCacheKey() { if (getMethod() == RxVolley.Method.POST) { return getUrl() + mParams.getUrlParams(); } else { return getUrl(); } } @Override public String getBodyContentType() { if (mParams.getContentType() != null) { return mParams.getContentType(); } else { return super.getBodyContentType(); } } @Override public ArrayList<HttpParamsEntry> getHeaders() { return mParams.getHeaders(); } @Override public byte[] getBody() { ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { mParams.writeTo(bos); } catch (IOException e) { Loger.debug("FormRequest#getBody()--->IOException writing to ByteArrayOutputStream"); } return bos.toByteArray(); } @Override public Response<byte[]> parseNetworkResponse(NetworkResponse response) { return Response.success(response.data, response.headers, HttpHeaderParser.parseCacheHeaders(getUseServerControl(), getCacheTime(), response)); } @Override protected void deliverResponse(ArrayList<HttpParamsEntry> headers, final byte[] response) { if (mCallback != null) { HashMap<String, String> map = new HashMap<>(headers.size()); for (HttpParamsEntry entry : headers) { map.put(entry.k, entry.v); } mCallback.onSuccess(map, response); } } @Override public Priority getPriority() { return Priority.IMMEDIATE; } }
利用 RxVolley 的自定義請求,在庫中內置了文件下載功能。你能夠使用
//下載進度(可選參數,不須要可不傳) listener = new ProgressListener() { @Override public void onProgress(long transferredBytes, long totalSize) { Loger.debug(transferredBytes + "======" + totalSize); } } //下載回調,內置了不少方法,詳細請查看源碼 //包括在異步響應的onSuccessInAsync():注不能作UI操做 //下載成功時的回調onSuccess() //下載失敗時的回調onFailure():例如無網絡,服務器異常等 HttpCallback callback = new HttpCallback(){ @Override public void onSuccessInAsync(byte[] t) { } @Override public void onSuccess(String t) { } @Override public void onFailure(int errorNo, String strMsg) { } } RxVolley.download(FileUtils.getSDCardPath() + "/a.apk", "https://www.oschina.net/uploads/osc-android-app-2.4.apk", listener, callback);
download()原型
既然說了下載功能是利用 RxVolley 的自定義請求建立的,不妨看看他的方法實現:github
/** * 下載 * * @param storeFilePath 本地存儲絕對路徑 * @param url 要下載的文件的url * @param progressListener 下載進度回調 * @param callback 回調 */ public static void download(String storeFilePath, String url, ProgressListener progressListener, HttpCallback callback) { RequestConfig config = new RequestConfig(); config.mUrl = url; FileRequest request = new FileRequest(storeFilePath, config, callback); request.setOnProgressListener(progressListener); new Builder().setRequest(request).doTask(); }
理論上來講,一切的請求設置均可以經過自定義 Request 來完成。
可是,若是你和我同樣是個懶人,固然更但願這些早就有人已經作好了。
默認的文件緩存路徑是在SD卡根目錄的 /RxVolley 文件夾下,你能夠經過以下語句設置你的 cacheFolder
RxVolley.setRequestQueue(RequestQueue.newRequestQueue(cacheFolder));
須要注意的是,setRequestQueue 方法必須在 RxVolley.Build() 方法執行以前調用,也就是在使用 RxVolley 之前先設置配置信息。建議在 Application 類中完成這些設置。緩存
若是不設置,默認信任所有的https證書。能夠傳入自定義 SSLSocketFactory
RxVolley.setRequestQueue(RequestQueue.newRequestQueue(cacheFolder), new HttpConnectStack(null, sslSocketFactory));
須要注意的是,setRequestQueue 方法必須在 RxVolley.Build() 方法執行以前調用,也就是在使用 RxVolley 之前先設置配置信息。建議在 Application 類中完成這些設置。
一個自定義設置SSLSocketFactory的相關示例:
//下載的證書放到項目中的assets目錄中 InputStream ins = context.getAssets().open("app_pay.cer"); CertificateFactory cerFactory = CertificateFactory .getInstance("X.509"); Certificate cer = cerFactory.generateCertificate(ins); KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC"); keyStore.load(null, null); keyStore.setCertificateEntry("trust", cer); SSLSocketFactory socketFactory = new SSLSocketFactory(keyStore); RxVolley.setRequestQueue(RequestQueue.newRequestQueue(RxVolley.CACHE_FOLDER), new HttpConnectStack(null, sslSocketFactory));
Build()中的可選設置
詳細請參閱 RxVolley$Builder 類中代碼。
//請求超時時間 timeout() //爲了更真實的模擬網絡,若是讀取緩存,延遲一段時間再返回緩存內容 delayTime() //緩存有效時間,單位分鐘 cacheTime() //使用服務器控制的緩存有效期,即cookie有效期 //(若是使用服務器端控制,則無視#cacheTime()) useServerControl() //啓用緩存 shouldCache() //重連策略,Volley默認的重連策略是timeout=3000,重試1次 retryPolicy()
RxVolley 默認對於 cookie 的操做是會從 HttpCallback 中返回 cookie,須要手動保存到本地。
若是你但願框架可以自動存儲 cookie,能夠這麼作:
按須要選擇繼承FormRequest或者JsonRequest (直接繼承 Request 類也能夠,可是複雜) 並重寫
@Override protected void deliverResponse(ArrayList<HttpParamsEntry> headers, final byte[] response) { if (mCallback != null) { HashMap<String, String> map = new HashMap<>(headers.size()); for (HttpParamsEntry entry : headers) { map.put(entry.k, entry.v); } mCallback.onSuccess(map, response); } }
邏輯如上述代碼,其中的map即包含了服務器返回的cookie,能夠作你本身的操做了。
最終執行你的自定義 Request
new RxVolley.Builder().setRequest(xxxxx).doTask();
在傳遞 Cookie 做爲請求頭的時候,建議寫一個工具類,例如服務器
public static HttpParams getHttpParams() { HttpParams params = new HttpParams(); params.putHeader("cookie"); return params; }
Volley 容許你建立本身的網絡請求執行器,執行器須要實現IHttpStack接口
RxVolley 的 okhttp module 已經有了使用 OkHttp 做爲請求執行器的實現。
你能夠使用以下代碼設置,依舊須要注意的是,setRequestQueue 方法必須在 RxVolley.Build() 方法執行以前調用,也就是在使用 RxVolley 之前先設置配置信息。建議在 Application 類中完成這些設置。
RxVolley.setRequestQueue(RequestQueue.newRequestQueue(RxVolley.CACHE_FOLDER, new OkHttpStack(new OkHttpClient())));
使用 OkHttp 相關功能須要在你的 build.gradle 文件中加入
compile 'com.kymjs.rxvolley:okhttp:1.0.5'