网络请求库和图片加载库
Posted nangongyibin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络请求库和图片加载库相关的知识,希望对你有一定的参考价值。
网络请求库
概述:所有网络库的原理是: 网络请求一般是基于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请求
public void click(View view) { Ion.with(this).load(Api.TEST).asString().setCallback(new FutureCallback<String>() { @Override public void onCompleted(Exception e, String result) { if (e == null) { String name = Thread.currentThread().getName(); Log.e(TAG, "onCompleted: " + name); tv.setText(name); } else { Log.e(TAG, "onCompleted: " + e.getMessage()); } } }); }
使用ion进行post请求,提交key-value形式的参数
public void click1(View view) { Ion.with(this).load(Api.LOGIN).setBodyParameter("username", "username").setBodyParameter("password", "password").asString().setCallback(new FutureCallback<String>() { @Override public void onCompleted(Exception e, String result) { if (e == null) { tv.setText(result); } } }); }
使用ion进行post请求,提交json对象参数
public void click1(View view) { Ion.with(this).load(Api.LOGIN).setBodyParameter("username", "username").setBodyParameter("password", "password").asString().setCallback(new FutureCallback<String>() { @Override public void onCompleted(Exception e, String result) { if (e == null) { tv.setText(result); } } }); }
使用ion进行上传文件,并显示进度
public void click2(View view) { Log.e(TAG, "click2: "); File file = new File(Environment.getExternalStorageDirectory(), "dog.jpg"); Log.e(TAG, "click2: " + file.getPath()); Ion.with(this).load(Api.UPLOAD).uploadProgress(new ProgressCallback() { @Override public void onProgress(long downloaded, long total) { Log.e(TAG, "onProgress: " + downloaded * 100 / total); } }) .setMultipartFile("file", file) .asString() .setCallback(new FutureCallback<String>() { @Override public void onCompleted(Exception e, String result) { if (e == null) { tv.setText(result); } } }); }
使用ion进行下载文件,并且显示进度
public void click3(View view) { File file = new File(Environment.getExternalStorageDirectory().getPath(), "a.jpg"); try { if (file.exists()) { file.delete(); } file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } Ion.with(getApplicationContext()).load(Api.IMAGE). progress(new ProgressCallback() { @Override public void onProgress(long downloaded, long total) { Log.e(TAG, "onProgress: " + downloaded * 100 / total); } }).write(file).setCallback(new FutureCallback<File>() { @Override public void onCompleted(Exception e, File result) { if (e == null) { Bitmap bitmap = BitmapFactory.decodeFile(result.getAbsolutePath()); tv.setBackgroundDrawable(new BitmapDrawable(bitmap)); Log.e(TAG, "onCompleted: " + result); } else { Log.e(TAG, "onCompleted: " + e.getMessage()); } } }); }
Retrofit的使用
详情查看https://github.com/square/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实例对象
Retrofit retrofit = new Retrofit.Builder().baseUrl(Api.SERVER_HOST).addConverterFactory(GsonConverterFactory.create()).build(); retrofitApi = retrofit.create(RetrofitApi.class);
定义业务逻辑接口
public interface RetrofitApi { @GET("test") Call<People> getTest(); @FormUrlEncoded @POST("login") Call<User> login(@Field("username") String username, @Field("password") String password); @GET("image") Call<ResponseBody> download(); @Multipart @POST("uploadMulti") Call<ResponseBody> upload(@PartMap Map<String, RequestBody> map); }
创建接口实例对象
retrofitApi = retrofit.create(RetrofitApi.class);
获取业务方法的调用对象,并进行请求
public void click1(View view) { Call<People> call = retrofitApi.getTest(); call.enqueue(new Callback<People>() { @Override public void onResponse(Call<People> call, Response<People> response) { People body = response.body(); Log.e(TAG, "onResponse: " + body.getNickname()); tv.setText(body.getNickname()); } @Override public void onFailure(Call<People> call, Throwable t) { } }); }
Retrofit的url注解处理
使用@Path注解来处理url路径不固定的需求,如
@GET("test/{order}")//获取订单的某段路径不固定,
@GET("test")
Call<People> getTest();
使用@Query注解来替换url后面跟的参数,如:
@FormUrlEncoded @POST("login") Call<User> login(@Field("username") String username, @Field("password") String password);
使用@QueryMap来替换多个查询参数,如
@Multipart @POST("uploadMulti") Call<ResponseBody> upload(@PartMap Map<String, RequestBody> map);
使用@Post注解进行post请求,提交key-value数据,如
@FormUrlEncoded @POST("login") Call<User> login(@Field("username") String username, @Field("password") String password);
使用@Post注解进行post请求,提交json数据,如
@GET("image")
Call<ResponseBody> download();
使用@Headers定义请求头,如
//定义请求头 @Headers({ "Accept: application/vnd.github.v3.full+json", "User-Agent: Retrofit-Sample-App" })
使用ResponseBody来接收流的数据,比如下载文件
@GET("image")
Call<ResponseBody> download();
使用@Muptipart和@Part或者@PartMao封装多块请求体
@Multipart @POST("uploadMulti") Call<ResponseBody> upload(@PartMap Map<String, RequestBody> map);
需要注意的是,构建RequestBody的时候要注意拼接:
public void click4(View view) { 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<ResponseBody> call = retrofitApi.upload(map); call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { try { String string = response.body().string(); tv.setText(string); } catch (IOException e) { e.printStackTrace(); } } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { Log.e(TAG, "onFailure: " + t.getLocalizedMessage()); } }); }
Volley的使用
介绍
谷歌开源的,专注于处理高频率的数据比较小的请求
内部仍然是使用的HttpURLConnection和HttpClient进行网络请求的,只是对于不同的Android版本进行了响应的切换,2.3之前使用的HttpClient,2.3之后使用的是HttpURLConnection
支持取消请求
具有网络请求和图片加载的功能
添加依赖
compile ‘com.android.volley:volley:1.0.0‘
创建RequestQueue请求队列,它是用来执行请求对象的
queue = Volley.newRequestQueue(this);
创建请求对象,这里使用最简单的StringRequest:
public void click(View view) { StringRequest stringRequest = new StringRequest(Api.TEST, new Response.Listener<String>() { @Override public void onResponse(String response) { tv.setText(response); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.e(TAG, "onErrorResponse: " + error.getLocalizedMessage()); } }); queue.add(stringRequest); }
执行请求,将Request对象添加到RequestQueue中,即可
public void click1(View view) { MyQuest request = new MyQuest(Request.Method.POST, Api.LOGIN, new Response.Listener<String>() { @Override public void onResponse(String response) { tv.setText(response); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.e(TAG, "onErrorResponse: " + error.getLocalizedMessage()); } }); HashMap<String, String> map = new HashMap<>(); map.put("username", "username"); map.put("password", "password"); request.setParam(map); queue.add(request); }
使用Volley发送post请求,需要自己重写Request的getParams方法
private class MyQuest extends StringRequest { private Map<String, String> param = null; public void setParam(Map<String, String> param) { this.param = param; } public MyQuest(String url, Response.Listener<String> listener, Response.ErrorListener errorListener) { super(url, listener, errorListener); } public MyQuest(int method, String url, Response.Listener<String> listener, Response.ErrorListener errorListener) { super(method, url, listener, errorListener); } protected Map<String, String> getParam() throws AuthFailureError { return param; } }
图片加载库
原理概述:图片加载的工作流(task flow)都是3级缓存的流程;图片的内存缓存一定是LruCache实现;图片下载和读取线程的调度一定是通过线程池管理
画图说明图片加载原理
Glide的使用
详情查看https://github.com/bumptech/glide
介绍:
专注于处理平滑滑动的图片类库
默认使用HttpUrlConnection下载图片
支持设置渐渐显示的动画
支持设置加载中的图片
添加依赖
compile ‘com.github.bumptech.glide:glide:3.7.0‘
使用Glide加载图片
Glide.with(this).load(Constants.IMAGES[1]).centerCrop().placeholder(R.mipmap.ic_launcher) .error(R.mipmap.ic_launcher).crossFade(500).into(iv);
Picasso的使用
详情查看https://github.com/square/picasso
介绍:
Square开源的比较早的图片加载类库
自动处理adapter中的ImageView的回收时取消下载图片
支持加载多种来源的图片,比如网络,sd卡,res资源
支持设置占位图片
支持对图片的自定义处理
添加依赖
compile ‘com.squareup.picasso:picasso:2.5.2‘
使用Picasso加载图片
Picasso.with(this) .load(Constants.IMAGES[1]) .centerCrop() .placeholder(R.mipmap.ic_launcher) .error(R.mipmap.ic_launcher) .noFade() .resize(200,140) .into(iv);
加载其他资源路径的图片
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的使用
详情查看https://github.com/facebook/fresco
介绍:
Facebook开源的专注于优化java堆内存,最大程度减少OOM
在Android4.4以及以下,将图片存储在Android的一块特殊的内存区域,这会让图片处理更加快速
支持Gif和WebP格式的图片
添加依赖
compile ‘com.facebook.fresco:fresco:0.11.0‘
首先初始化Fresco,一般在Application的onCreate中初始化
Fresco.initialize(getApplicationContext());
使用Fresco提供的SimpleDraweeView显示图片
iv.setImageURI(Constants.IMAGES[1]);
由于使用的是自定义控件加载图片,那么通过定义属性来进行设置:
<com.facebook.drawee.view.SimpleDraweeView android:id="@+id/iv" android:layout_width="200dp" android:layout_height="140dp" fresco:actualImageScaleType="centerCrop" fresco:fadeDuration="300" fresco:failureImage="@mipmap/dialog_title_default_icon" fresco:failureImageScaleType="centerInside" fresco:placeholderImage="@mipmap/ic_launcher" fresco:placeholderImageScaleType="fitCenter" fresco:pressedStateOverlayImage="@color/colorRed" fresco:progressBarAutoRotateInterval="1000" fresco:progressBarImage="@mipmap/loading" fresco:progressBarImageScaleType="centerInside" fresco:retryImage="@mipmap/dialog_title_default_icon" fresco:retryImageScaleType="centerCrop" fresco:roundAsCircle="true" fresco:roundBottomLeft="false" fresco:roundBottomRight="true" fresco:roundTopLeft="true" fresco:roundTopRight="false" fresco:roundedCornerRadius="15dp" fresco:roundingBorderColor="@color/colorAccent" fresco:roundingBorderWidth="2dp" />
属性解释:
placeholderImage就是所谓的展位图啦,在图片没有加载出来之前你看到的就是它
failureIamge看到名字就知道是什么了,图片加载失败时显示的图片就是它了
retryImage图片加载失败时显示,提示用户点击重新加载,重复加载4次还是没有加载出来的时候才会显示failureImage的图片
progressBarImage进度条图片
backgroundImage背景图片,这里的背景图片首先被绘制
overlayImage设置叠加图,在xml中只能设置一张叠加图片,如果需要多张图片的话,需要在java代码中设置哦
pressedStateOverlayImage设置点击状态下的叠加图,此叠加图不能缩放
ImageScaleType这个就是各种各样的图片缩放样式了,center,centerCrop,fouseCrop,centerInside,fitCenter,fitStart,fitEnd,fitXY
以上是关于网络请求库和图片加载库的主要内容,如果未能解决你的问题,请参考以下文章