全部網絡庫的原理是: 網絡請求通常是基於HttpURLConnection和HttpClient進行封裝的,也有本身編寫Socket實現的,好比ion和OkHttp;請求的執行通常是經過線程池來管理,異步請求獲得結果,則經過回調接口接收;而且通常接收結果的回調都經過Handler去在主線程執行java
詳情查看Github主頁https://github.com/koush/ionandroid
添加依賴git
dependencies { compile 'com.koushikdutta.ion:ion:2.+' }
使用ion進行get請求github
Ion.with(this) .load(Api.TEST) .asString()//以字符串形式返回,服務器返回的都是流,只是類庫將流轉爲字符串了 .setCallback(callback);//設置接收結果的回調接口 FutureCallback<String> callback = new FutureCallback<String>() { /** * 回調是在主線程執行的,因此能夠直接更新UI * @param e * @param result */ @Override public void onCompleted(Exception e, String result) { text.setText(e == null ? result : e.getMessage()); } };
使用ion進行post請求,提交key-value形式的參數apache
Ion.with(this) .load(Api.LOGIN) .setBodyParameter("username","俊哥")//設置請求參數 .setBodyParameter("password","123") .asString() .setCallback(callback);
使用ion進行post請求,提交json對象參數json
//構造json對象 JsonObject json = new JsonObject(); json.addProperty("city","北京"); json.addProperty("year","2016"); Ion.with(this) .load(Api.POST_JSON) .setJsonObjectBody(json) .asString() .setCallback(callback);
使用ion進行上傳文件,並顯示進度api
File file = new File(Environment.getExternalStorageDirectory(),"dog.jpg"); Ion.with(this) .load(Api.UPLOAD) .uploadProgress(new ProgressCallback() { @Override public void onProgress(long downloaded, long total) { int percent = (int) (downloaded*100f/total+0.5f); Log.e("tag","上傳進度:"+percent+"%"); } }) .setMultipartFile("file",file) .asString() .setCallback(callback);
使用ion進行下載文件,而且顯示進度緩存
File file = new File(Environment.getExternalStorageDirectory(),"a.jpg"); Ion.with(this) .load(Api.IMAGE) .progress(new ProgressCallback() { @Override public void onProgress(long downloaded, long total) { int percent = (int) (downloaded*100f/total+0.5f); text.setText("下載進度:"+percent+"%"); } }) .write(file) .setCallback(new FutureCallback<File>() { @Override public void onCompleted(Exception e, File file) { text.setText("下載成功:"+file.getAbsolutePath()); } });
介紹服務器
添加依賴
compile 'com.squareup.retrofit2:retrofit:2.1.0' compile 'com.squareup.retrofit2:converter-gson:2.0.2'
建立Retrofit實例對象
//建立Retrofit Retrofit retrofit = new Retrofit.Builder() //注意,服務器主機應該以/結束, .baseUrl("http://192.168.2.103:8080/apitest/")//設置服務器主機 .addConverterFactory(GsonConverterFactory.create())//配置Gson做爲json的解析器 .build();
定義業務邏輯接口
public interface HeiMaApi { /** * 定義了一個業務方法,獲取訂單, */ @GET("test")//指定該方法要請求的url,注意方法的路徑不要以/開頭,如/test,是錯誤的 Call<Stu> getOrder(); }
建立接口實例對象
HeiMaApi heiMaApi = retrofit.create(HeiMaApi.class);
獲取業務方法的調用對象,並進行請求
//調用業務方法,獲得要執行的業務請求對象 Call<Stu> order = heiMaApi.getOrder(); //執行請求對象 //1.同步執行,獲得響應對象,會阻塞UI,不推薦 //Response<Stu> response = order.execute(); //Stu stu = response.body(); //2.異步執行業務方法 order.enqueue(new Callback<Stu>() { @Override public void onResponse(Call<Stu> call, Response<Stu> response) { Stu stu = response.body(); text.setText(stu.toString()); } @Override public void onFailure(Call<Stu> call, Throwable t) { } });
Retrofit的url註解處理
使用@Path註解來處理url路徑不固定的需求,如
@GET("test/{order}")//獲取訂單的某段路徑不固定, Call<Stu> getOrder(@Path("order")String order);
使用@Query註解來替換url後面跟的參數,如:
//url爲:test?id=333 //使用@Query來替換查詢參數 @GET("test") Call<Stu> getOrderById(@Query("id") String id);
使用@QueryMap來替換多個查詢參數,如
//假設url爲:login?username=heima&password=111 //使用@QueryMay來替換多個查詢參數 @GET("login") Call<Stu> login(@QueryMap Map<String,String> map);
使用@Post註解進行post請求,提交key-value數據,如
@FormUrlEncoded//配置對請求體參數進行url編碼 @POST("login") Call<Login> postLogin(@Field("username")String username, @Field("password")String password);
使用@Post註解進行post請求,提交json數據,如
//使用@Body設置請求體參數 //注意,@Body不須要配置@FormUrlEncoded或者@Multipart @POST("login") Call<Login> postJson(@Body JsonObject jsonObject);
使用@Headers定義請求頭,如
//定義請求頭 @Headers({ "Accept: application/vnd.github.v3.full+json", "User-Agent: Retrofit-Sample-App" })
使用ResponseBody來接收流的數據,好比下載文件
//下載文件 @GET("image") Call<ResponseBody> getImage();
使用@Muptipart和@Part或者@PartMao封裝多塊請求體
//上傳文件和其餘參數 @Multipart//將請求體進行Multipart拼接 @POST("uploadMulti") //RequestBody表示數據和數據類型的封裝體 //Call<UploadResult> upload(@Part("file") RequestBody file,@Part("params1") RequestBody params1); //或者使用@PartMap Call<UploadResult> upload(@PartMap Map<String, RequestBody> map);
須要注意的是,構建RequestBody的時候要注意拼接:
File file = new File(Environment.getExternalStorageDirectory(),"a.jpg"); File file2 = new File(Environment.getExternalStorageDirectory(),"dog.jpg"); RequestBody fileBody = RequestBody.create(MediaType.parse("image/jpeg"),file); RequestBody fileBody2 = RequestBody.create(MediaType.parse("image/jpeg"),file2); HashMap<String,RequestBody> map = new HashMap<>(); map.put("file\"; filename=\""+file.getName(),fileBody); map.put("file\"; filename=\""+file2.getName(),fileBody2); Call<UploadResult> uploadResultCall = HeiMaClient.create().heiMaApi.upload(map); uploadResultCall.enqueue(new Callback<UploadResult>() { @Override public void onResponse(Call<UploadResult> call, Response<UploadResult> response) { text.setText(response.body().toString()); } @Override public void onFailure(Call<UploadResult> call, Throwable t) { } });
添加依賴
compile 'com.android.volley:volley:1.0.0'
建立RequestQueue請求隊列,它是用來執行請求對象的
RequestQueue queue = Volley.newRequestQueue(this);
建立請求對象,這裏使用最簡單的StringRequest:
StringRequest stringRequest = new StringRequest(Api.TEST, new com.android.volley.Response.Listener<String>() { @Override public void onResponse(String response) { text.setText(response); } }, new com.android.volley.Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { } });
執行請求,將Request對象添加到RequestQueue中,便可
//3.執行請求 queue.add(stringRequest);
使用JsonRequest進行請求,返回的是json對象
//1.建立JsonRequest請求 JsonObjectRequest joRequest = new JsonObjectRequest(url, null, new Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { tv_result.setText(response.toString()); } }, new MyErrorListener()); //2.執行請求 queue.add(joRequest);
使用Volley發送post請求,須要本身重寫Request的getParams方法
public class PostReuqest extends StringRequest { private Map<String, String> params; public PostReuqest(String url, Response.Listener<String> listener, Response.ErrorListener errorListener) { super(url, listener, errorListener); } public PostReuqest(int method,String url, Response.Listener<String> listener, Response.ErrorListener errorListener) { super(method,url, listener, errorListener); } public void setParams(Map<String, String> params){ this.params = params; } @Override protected Map<String, String> getParams() throws AuthFailureError { return params; } } PostReuqest stringRequest = new PostReuqest(Request.Method.POST,Api.LOGIN, new com.android.volley.Response.Listener<String>() { @Override public void onResponse(String response) { text.setText(response); } }, new com.android.volley.Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { } }); HashMap<String,String> map = new HashMap<>(); map.put("username","hehehe"); map.put("password","12321"); stringRequest.setParams(map);