Android图片加载库、网络框架

本文简单汇总Android中图片加载库的使用,并非深度源码的解析。

Android-Universal-Image-Loader

项目地址:Android-Universal-Image-Loader

 
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 
     
// 初始化相关
ImageLoader imageLoader = ImageLoader.getInstance(); // Get singleton instance
imageLoader.init(ImageLoaderConfiguration.createDefault(BDApplication.instance()));
// 使用方式1:根据uri显示到ImageView上,是否异步要根据option.isSyncLoading
// Load image, decode it to Bitmap and display Bitmap in ImageView (or any other view
// which implements ImageAware interface)
imageLoader.displayImage(imageUri, imageView);
// 使用方式2:在回调里处理
// Load image, decode it to Bitmap and return Bitmap to callback
imageLoader.loadImage(imageUri, new SimpleImageLoadingListener() {
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
// Do whatever you want with Bitmap
}
});
// 使用方式3:同步返回bitmap
// Load image, decode it to Bitmap and return Bitmap synchronously
Bitmap bmp = imageLoader.loadImageSync(imageUri);

另外,可以配置显示图片的样式,设置option的BitmapDisplayer。UIL提供了FadeInBitmapDisplayer渐显样式、SimpleBitmapDisplayer、RoundedBitmapDisplayer、CircleBitmapDisplayer、RoundedVignetteBitmapDisplayer圆角显示颜色会有个渐变的效果 这5中Displayer。

 
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 
     
private ImageLoaderUtil() {
// 正常图片
optionsNormal = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_stub)
.showImageForEmptyUri(R.drawable.ic_stub)
.showImageOnFail(R.drawable.ic_stub).cacheInMemory( true)
.cacheOnDisk( true).considerExifParams( true)
.displayer( new SimpleBitmapDisplayer()).build();
// 圆角矩形
optionsRounded = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_stub)
.showImageForEmptyUri(R.drawable.ic_stub)
.showImageOnFail(R.drawable.ic_stub).cacheInMemory( true)
.cacheOnDisk( true).considerExifParams( true)
.displayer( new RoundedBitmapDisplayer( 10)).build();
// 圆圈图片
optionsCircle = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_stub)
.showImageForEmptyUri(R.drawable.ic_stub)
.showImageOnFail(R.drawable.ic_stub).cacheInMemory( true)
.cacheOnDisk( true).considerExifParams( true)
.displayer( new CircleBitmapDisplayer( 4)).build();
imageLoader = ImageLoader.getInstance();
imageLoader.init(ImageLoaderConfiguration.createDefault(BDApplication.instance()));
animateFirstListener = new AnimateFirstDisplayListener();
}

总体架构图:

流程图:

参考文档:
Android Universal Image Loader 源码分析

google/volley

官方项目地址:volley
fork项目地址:volley-mstian06
Demo项目地址:android-cn/volley-demo

类继承关系图:

总体设计图

 
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
 
     
// 初始化相关
public class RequestManager {
public static RequestQueue mRequestQueue = newRequestQueue();
private static final int MEM_CACHE_SIZE = 1024 * 1024 * ((ActivityManager) AppData.getContext()
.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass() / 3;
private static ImageLoader mImageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache(MEM_CACHE_SIZE));
private static DiskBasedCache mDiskCache = (DiskBasedCache) mRequestQueue.getCache();
private RequestManager(){
}
// DiskLruCache缓存,自定义路径、大小
private static Cache openCache() {
return new DiskBasedCache(CacheUtils.getExternalCacheDir(AppData.getContext()),
10 * 1024 * 1024);
}
private static RequestQueue newRequestQueue() {
RequestQueue requestQueue = new RequestQueue(openCache(), new BasicNetwork( new HurlStack()));
requestQueue.start();
return requestQueue;
}
public static void addRequest(Request request, Object tag) {
if (tag != null) {
request.setTag(tag);
}
mRequestQueue.add(request);
}
public static void cancelAll(Object tag) {
mRequestQueue.cancelAll(tag);
}
public static ImageLoader. ImageContainer loadImage(String requestUrl,
ImageLoader.ImageListener imageListener) {
return loadImage(requestUrl, imageListener, 0, 0);
}
public static ImageLoader. ImageContainer loadImage(String requestUrl,
ImageLoader.ImageListener imageListener, int maxWidth, int maxHeight) {
return mImageLoader.get(requestUrl, imageListener, maxWidth, maxHeight);
}
}
public class CacheUtils {
public static File getExternalCacheDir(final Context context) {
if (hasExternalCacheDir())
return context.getExternalCacheDir();
// Before Froyo we need to construct the external cache dir ourselves
final String cacheDir = "/Android/data/" + context.getPackageName() + "/cache/";
return new File(Environment.getExternalStorageDirectory().getPath() + cacheDir);
}
public static boolean hasExternalCacheDir() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO;
}
}
// LruCache内存缓存
public class BitmapLruCache extends LruCache<String, Bitmap> implements ImageLoader.ImageCache {
public BitmapLruCache(int maxSize) {
super(maxSize);
}
@Override
protected int sizeOf(String key, Bitmap bitmap) {
return ImageUtils.getBitmapSize(bitmap);
}
@Override
public Bitmap getBitmap(String url) {
return get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
put(url, bitmap);
}
}

应用:

 
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
 
     
// case1: StringRequest
StringRequest request = new StringRequest(StringUtil.preUrl(etUrl.getText().toString().trim()),
new Listener<String>() {
@Override
public void onResponse(String response) {
tvResult.setText(response);
}
}, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError arg0) {
ToastUtil.showToast(getActivity(), getResources().getString(R.string.request_fail_text));
}
});
RequestManager.addRequest(request, this);
// case2: JsonObjectRequest,同理JsonArrayRequest
JsonObjectRequest request = new JsonObjectRequest(StringUtil.preUrl(Constants.DEFAULT_JSON_REQUEST_URL), null,
new Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
// 解析JSON代码...
JSONArray seriesArray = factory.getJSONArray( "serieslist");
carDataList.clear();
for ( int i = 0; i < seriesArray.length(); i++) {
JSONObject series = seriesArray.getJSONObject(i);
Map<String, String> seriesMap = new HashMap<String, String>();
seriesMap.put( "name", series.getString( "name"));
seriesMap.put( "level", "级别:"+series.getString( "levelname"));
seriesMap.put( "price", "价格:"+series.getString( "price"));
carDataList.add(seriesMap);
}
adapter.notifyDataSetChanged();
} catch (Exception e) {
ToastUtil.showToast(getActivity(), getResources().getString(R.string.request_fail_text));
}
}
}, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError arg0) {
ToastUtil.showToast(getActivity(), getResources().getString(R.string.request_fail_text));
}
});
RequestManager.addRequest(request, this);
// case3: ImageRequest
ImageRequest request= new ImageRequest(StringUtil.preUrl(imageUrl), new Listener<Bitmap>() {
@Override
public void onResponse(Bitmap bitmap) {
imageView.setImageBitmap(bitmap);
}}, 0, 0, Config.RGB_565, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError arg0) {
imageView.setImageResource(R.drawable.ic_empty);
}
});
RequestManager.addRequest(request, this);
// case4: ImageLoader
ImageListener listener=ImageLoader.getImageListener(imageView, R.drawable.ic_empty, R.drawable.ic_error);
ImageLoader.ImageContainer container = RequestManager.loadImage(StringUtil.preUrl(imageUrl), listener);
//在ImageView上存储当前请求的Container,用于取消请求
imageView.setTag(container);
// case5: NetworkImageView
NetworkImageView networkImageView=(NetworkImageView)imageView;
networkImageView.setDefaultImageResId(R.drawable.ic_empty);
networkImageView.setErrorImageResId(R.drawable.ic_error);
networkImageView.setImageUrl(StringUtil.preUrl(imageUrl), RequestManager.getImageLoader());
// case6: Post请求,重写getParams方法,传递Post参数
StringRequest request = new StringRequest(Method.POST, StringUtil.preUrl(etUrl.getText().toString().trim()), listener, errorListener) {
//重写getParams设置post请求的参数
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> paramMap = new HashMap<String, String>();
try {
String paramsStr = etParams.getText().toString().trim();
String[] paramsArray = paramsStr.split( ";");
for (String param : paramsArray) {
paramMap.put(keyValueArray[ 0].trim(), keyValueArray.length > 1 ? keyValueArray[ 1].trim() : "");
}
} catch (Exception e) {
ToastUtil.showToast(getActivity(), "参数格错误");
}
return paramMap;
}
};
RequestManager.addRequest(request, this);
// 注:JsonObjectRequest可根据第二个参数来决定是GET还是POST
public JsonObjectRequest(String url, JSONObject jsonRequest, Listener<JSONObject> listener,
ErrorListener errorListener) {
this(jsonRequest == null ? Method.GET : Method.POST, url, jsonRequest,
listener, errorListener);
}
// case7: 自定义Request,使用GSON解析JSON
public class GsonRequest<T> extends Request<T> {
private final Gson gson = new Gson();
private final Class<T> clazz;
private final Map<String, String> headers;
private final Listener<T> listener;
public GsonRequest(String url, Class<T> clazz, Map<String, String> headers,
Listener<T> listener, ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.clazz = clazz;
this.headers = headers;
this.listener = listener;
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers != null ? headers : super.getHeaders();
}
@Override
protected void deliverResponse(T response) {
listener.onResponse(response);
}
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
// String json = Test.getFromAssets("test.txt", AppData.getContext());//yes
// String json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));//no
String json = new String(response.data);
return Response.success(
gson.fromJson(json, clazz), HttpHeaderParser.parseCacheHeaders(response));
} catch (JsonSyntaxException e) {
e.printStackTrace();
return Response.error( new ParseError(e));
} catch (Exception e) {
e.printStackTrace();
return Response.error( new ParseError(e));
}
}
}

参考文档
Volley 源码解析
Android Volley完全解析(一),初识Volley的基本用法

glide(未研究)

项目地址:glide

 
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 
     
// For a simple view:
@Override public void onCreate(Bundle savedInstanceState) {
...
ImageView imageView = (ImageView) findViewById(R.id.my_image_view);
Glide.with( this).load( "http://goo.gl/gEgYUd").into(imageView);
}
// For a simple image list:
@Override public View getView(int position, View recycled, ViewGroup container) {
final ImageView myImageView;
if (recycled == null) {
myImageView = (ImageView) inflater.inflate(R.layout.my_image_view, container, false);
} else {
myImageView = (ImageView) recycled;
}
String url = myUrls.get(position);
Glide
.with(myFragment)
.load(url)
.centerCrop()
.placeholder(R.drawable.loading_spinner)
.crossFade()
.into(myImageView);
return myImageView;
}

参考文档
Google推荐的图片加载库Glide介绍-译文

square/picasso

项目地址:square/picasso

使用

 
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
     
@Override public void getView(int position, View convertView, ViewGroup parent) {
SquaredImageView view = (SquaredImageView) convertView;
if (view == null) {
view = new SquaredImageView(context);
}
String url = getItem(position);
Picasso.with(context).load(url).into(view);
}
Picasso.with(context)
.load(url)
.placeholder(R.drawable.user_placeholder)
.error(R.drawable.user_placeholder_error)
.into(imageView);
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);

参考文档
官方文档
Android图片加载库Picasso源码分析
picasso-强大的Android图片下载缓存库

facebook/fresco(待研究)

项目地址:facebook/fresco

应用

 
     
1
2
3
 
     
Uri uri = Uri.parse( "https://raw.githubusercontent.com/facebook/fresco/gh-pages/static/logo.png");
SimpleDraweeView draweeView = (SimpleDraweeView) findViewById(R.id.my_image_view);
draweeView.setImageURI(uri);

参考文档
中文站
FaceBook推出的Android图片加载库-Fresco
Android图片加载神器之Fresco-加载图片基础
Fresco图片框架内部实现原理探索

android-async-http

项目地址:android-async-http

最主要的类:

 
     
1
2
3
 
     
AsyncHttpResponseHandler
AsyncHttpClient
AsyncHttpRequest

类继承关系图:

流程图

使用比较简单:

 
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
     
AsyncHttpClient client = new AsyncHttpClient();
client.get( "https://www.google.com", new AsyncHttpResponseHandler() {
@Override
public void onStart() {
// called before request is started
}
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
// called when response HTTP status is "200 OK"
}
@Override
public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
// called when response HTTP status is "4XX" (eg. 401, 403, 404)
}
@Override
public void onRetry(int retryNo) {
// called when request is retried
}
});

建议使用静态单例:

 
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 
     
import com.loopj.android.http.*;
public class TwitterRestClient {
private static final String BASE_URL = "https://api.twitter.com/1/";
private static AsyncHttpClient client = new AsyncHttpClient();
public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
client.get(getAbsoluteUrl(url), params, responseHandler);
}
public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
client.post(getAbsoluteUrl(url), params, responseHandler);
}
private static String getAbsoluteUrl(String relativeUrl) {
return BASE_URL + relativeUrl;
}
}
// 使用
import org.json.*;
import com.loopj.android.http.*;
class TwitterRestClientUsage {
public void getPublicTimeline() throws JSONException {
TwitterRestClient.get( "statuses/public_timeline.json", null, new JsonHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
// If the response is JSONObject instead of expected JSONArray
}
@Override
public void onSuccess(int statusCode, Header[] headers, JSONArray timeline) {
// Pull out the first event on the public timeline
JSONObject firstEvent = timeline.get( 0);
String tweetText = firstEvent.getString( "text");
// Do something with the response
System.out.println(tweetText);
}
});
}
}

参考文档
官网
android-async-http框架库使用基础

square/okhttp

项目地址
square/okhttp

参考文档
官网
wiki

square/retrofit

项目地址
square/retrofit

ThinkAndroid

项目地址:ThinkAndroid

参考文章:
Android Universal Image Loader 源码分析-codekk
Volley 源码解析-codekk
Android Volley完全解析(一),初识Volley的基本用法-guolin
Android 三大图片缓存原理、特性对比-Trnea

猜你喜欢

转载自blog.csdn.net/maoshengdev/article/details/78228606
今日推荐