熟練掌握目前最流行網絡請求類庫的使用,如:
- Ion:Android Asynchronous Networking and Image Loading
- Volley:谷歌官方推出的網絡請求和圖片加載庫
- Retrofit:Square開源的基於OKHttp的性能良好更安全的類庫
熟練掌握目前最流行圖片加載類庫的使用,如:
- Glide:專注於處理流暢加載的圖片類庫
- Picasso:Square開源的強大的效率高的圖片加載類庫
- Fresco:Facebook開源的專注於優化java堆內存的圖片加載類庫
網絡請求庫
概述:所有網絡庫的原理是: 網絡請求一般是基於HttpURLConnection和HttpClient進行封裝的,也有自己編寫Socket實現的,比如ion和OkHttp;請求的執行一般是通過線程池來管理,異步請求得到結果,則通過回調接口接收;並且一般接收結果的回調都通過Handler去在主線程執行
Ion的使用
詳情查看Github主頁https://github.com/koush/ion
介紹:
- 它支持網絡請求和進行圖片加載的雙重功能
- 擁有鏈式api風格(Fluent API)
- 當Activity結束的時候支持自動的取消操作
- 支持SPDY/HTTP2,緩存,Gzip壓縮,HTTP連接的重用等
- 並且是基於AndroidAsync實現的,AndroidAsync是作者的另一個使 用socket實現的,遵循http協議的類庫
添加依賴
dependencies {
compile 'com.koushikdutta.ion:ion:2.+'
}
使用ion進行get請求
Ion.with(this)
.load(Api.HELLO) //參數爲url
.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形式的參數
Ion.with(this)
.load(Api.LOGIN)
.setBodyParameter("username","張三")//設置請求參數
.setBodyParameter("password","123")
.asString()
.setCallback(callback);
使用ion進行post請求,提交json對象參數
//構造json對象
JsonObject json = new JsonObject();
json.addProperty("city","北京");
json.addProperty("year","2016");
Ion.with(this)
.load(Api.LOGIN)
.setJsonObjectBody(json)
.asString()
.setCallback(callback);
使用ion進行上傳文件,並顯示進度
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)//(MultipartFile 多文件上傳)長傳文件
.asString()
.setCallback(callback);
使用ion進行下載文件,並且顯示進度
File file = new File(Environment.getExternalStorageDirectory(),"a.jpg");
Ion.with(this)
.load(Api.DOWNLOAD)
.progress(new ProgressCallback() {
@Override
public void onProgress(long downloaded, long total) {
int percent = (int) (downloaded*100f/total+0.5f);
Log.e("tag","下載進度:"+percent+"%");
}
})
.write(file)
.setCallback(new FutureCallback<File>() {
@Override
public void onCompleted(Exception e, File file) {
text.setText("下載成功:"+file.getAbsolutePath());
}
});
Retrofit的使用
介紹
- Square公司爲Android開源的類型安全的Http客戶端
- 底層基於OkHttp,使用OkHttp進行請求
- 將java API的定義轉換爲interface形式
- 使用annotation描述http請求
- 支持配置json解析器
- 添加依賴
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
Retrofit發送get請求
1創建Retrofit實例對象
//創建Retrofit
Retrofit retrofit = new Retrofit.Builder()
//注意,服務器主機應該以/結束,
.baseUrl(Api.BASE_URL)//設置服務器主機
.addConverterFactory(GsonConverterFactory.create())//配置Gson作爲json的解析器
.build();
2定義業務邏輯接口
public interface HeiMaApi {
/**
* 定義了一個業務方法,獲取訂單,
*/
@GET("test")//結果就是第一步的Api.BASE_URL+“test”
Call<Stu> getOrder();//如果沒有使用轉換器的話,默認的泛型類型爲ResponseBody,
3創建接口實例對象
HeiMaApi heiMaApi = retrofit.create(HeiMaApi.class);
4獲取業務方法的調用對象,並進行請求
//調用業務方法,得到要執行的業務請求對象
Call<Stu> order = heiMaApi.getOrder();
//執行請求對象
//1.同步執行,得到響應對象,會阻塞UI,不推薦
//Response<Stu> response = order.execute();
//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);
Retrofit發送post請求
使用@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);
Retrofit下載
使用ResponseBody來接收流的數據,比如下載文件
/下載文件
@GET("image")
Call<ResponseBody> getImage();
Retrofit上傳文件
使用@Muptipart和@Part或者@PartMao封裝多塊請求體
//上傳文件和其他參數
@Multipart//將請求體進行Multipart拼接
@POST("uploadMulti") //RequestBody表示數據和數據類型的封裝體
Call<ResponseBody> upload(@Part("file") RequestBody file,@Part("params1") RequestBody params1);
//或者使用@PartMap
Volley的使用
介紹
- 谷歌開源的,專注於處理高頻率的數據比較小的請求
- 內部仍然是使用的HttpURLConnection和HttpClient進行網絡請求 的,只是對於不同的Android版本進行了響應的切換,
- 2.3之前使用的 HttpClient,2.3之後使用的是HttpURLConnection
- 支持取消請求
- 具有網絡請求和圖片加載的功能
添加依賴
compile 'com.android.volley:volley:1.0.0'
1 創建RequestQueue請求隊列,它是用來執行請求對象的
RequestQueue queue = Volley.newRequestQueue(this);
2 創建請求對象,這裏使用最簡單的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) {
}
});
3 執行請求,將Request對象添加到RequestQueue中,即可
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 {
public Map<> params;
public PostReuqest(String url, Response.Listener<> 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<> params){
this.params = params;
}
@Override
protected Map<> 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<> map = new HashMap<>();
map.put("username","hehehe");
map.put("password","12321");
stringRequest.setParams(map);
圖片加載庫
圖片加載額流程
Glide使用
介紹:
- 專注於處理平滑滑動的圖片類庫
- 默認使用HttpUrlConnection下載圖片
- 支持設置漸漸顯示的動畫
- 支持設置加載中的圖片
添加依賴
compile 'com.github.bumptech.glide:glide:3.7.0'
使用Glide加載圖片
Glide.with(this)
.load("")//參數爲地址
.centerCrop()//設置從中間剪切
.placeholder(R.mipmap.ic_launcher)//設置加載過程中顯示的圖片
.error(R.mipmap.ic_launcher)//設置加載失敗顯示的圖片
.crossFade()//設置漸漸顯示的效果
.into(image);//展示圖片,參數爲顯示的控件
Picasso的使用
介紹:
- Square開源的比較早的圖片加載類庫
- 自動處理adapter中的ImageView的回收時取消下載圖片
- 支持加載多種來源的圖片,比如網絡,sd卡,res資源
- 支持設置佔位圖片
支持對圖片的自定義處理
添加依賴
compile 'com.squareup.picasso:picasso:2.5.2'
使用Picasso加載圖片
Picasso.with(this)
.load("url")
.placeholder(R.mipmap.ic_launcher)
.error(R.mipmap.ic_launcher)
.centerCrop()
.noFade()//設置不需要漸漸顯示的動畫效果
.resize(120,120)//指定壓縮參考的寬高比
.into(image);
加載其他資源路徑的圖片
Picasso.with(context).load(R.drawable.landing_screen).into(imageView1);
Picasso.with(context).load("file:///android_asset/DvpvklR.png").into(imageView2);
Picasso.with(context).load(new File(...)).into(imageView3);
注意:如果不設置resize(120,120),則Picasso會加載整個圖片,顯然這樣消耗的內存比較大,一般都需要指定一下,而Glide內部已經默認參考了控件的寬高來進行縮放了。
Fresco的使用
介紹:
- Facebook開源的專注於優化java堆內存,最大程度減少OOM
- 在Android4.4以及以下,將圖片存儲在Android的一塊特殊的內存區域,這會讓圖片處理更加快速
- 支持Gif和WebP格式的圖片
添加依賴
compile 'com.facebook.fresco:fresco:0.11.0'
1首先初始化Fresco,一般在Application的onCreate中初始化
//先初始化Fresco
Fresco.initialize(this);
2在layout界面把imageView換成自己的控件
com.facebook.drawee.view.SimpleDraweeView
3使用Fresco提供的SimpleDraweeView顯示圖片
draweeView.setImageURI("url");
由於使用的是自定義控件加載圖片,那麼通過定義屬性來進行設置:
com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/image_view"
android:layout_width="300dp"
android:layout_height="300dp"
fresco:fadeDuration="300"
fresco:actualImageScaleType="focusCrop"
fresco:placeholderImage="@color/wait_color"
fresco:placeholderImageScaleType="fitCenter"
fresco:failureImage="@drawable/error"
fresco:failureImageScaleType="centerInside"
fresco:retryImage="@drawable/retrying"
fresco:retryImageScaleType="centerCrop"
fresco:progressBarImage="@drawable/progress_bar"
fresco:progressBarImageScaleType="centerInside"
fresco:progressBarAutoRotateInterval="1000"
fresco:backgroundImage="@color/blue"
fresco:overlayImage="@drawable/watermark"
fresco:roundAsCircle="false"
fresco:roundedCornerRadius="1dp"
fresco:roundTopLeft="true"
fresco:roundTopRight="false"
fresco:roundBottomLeft="false"
fresco:roundBottomRight="true"
fresco:roundWithOverlayColor="@color/corner_color"
fresco:roundingBorderWidth="2dp"
fresco:roundingBorderColor="@color/border_color"
/>
屬性解釋:
placeholderImage就是所謂的展位圖啦,在圖片沒有加載出來之前你看到的就是它
failureIamge看到名字就知道是什麼了,圖片加載失敗時顯示的圖片就是它了
retryImage圖片加載失敗時顯示,提示用戶點擊重新加載,重複加載4次還是沒有加載出來的時候纔會顯示failureImage的圖片
progressBarImage進度條圖片
backgroundImage背景圖片,這裏的背景圖片首先被繪製
overlayImage設置疊加圖,在xml中只能設置一張疊加圖片,如果需要多張圖片的話,需要在java代碼中設置
ImageScaleType這個就是各種各樣的圖片縮放樣式了,center,centerCrop,fouseCrop,centerInside,fitCenter,fitStart,fitEnd,fitXY