先来一个普通的加载图片的方法。
1 import android.annotation.SuppressLint; 2 import android.app.Activity; 3 import android.graphics.Bitmap; 4 import android.os.Bundle; 5 import android.os.Handler; 6 import android.os.Message; 7 import android.util.Log; 8 import android.view.Menu; 9 import android.view.View; 10 import android.view.View.OnClickListener; 11 import android.widget.Button; 12 import android.widget.EditText; 13 import android.widget.ImageView; 14 import android.widget.Toast; 15 16 import com.example.androiddemo.utils.GetImgUtil; 17 18 public class PictureActivity extends Activity { 19 20 String url = "http://img2.duitang.com/uploads/item/201208/18/20120818150713_zarnG.jpeg"; 21 private EditText edtUrl; 22 private Button btnGetpic; 23 private ImageView imgPic; 24 25 private Bitmap bmp; 26 @Override 27 protected void onCreate(Bundle savedInstanceState) { 28 super.onCreate(savedInstanceState); 29 setContentView(R.layout.activity_picture); 30 edtUrl = (EditText) findViewById(R.id.edt_url); 31 btnGetpic = (Button) findViewById(R.id.btn_getpic); 32 imgPic = (ImageView) findViewById(R.id.img_show); 33 edtUrl.setText(url); 34 btnGetpic.setOnClickListener(new OnClickListener() { 35 @Override 36 public void onClick(View arg0) { 37 //为了不造成阻塞,启动一个工作线程 38 new Thread(getPicByUrl).start(); 39 } 40 }); 41 } 42 43 Runnable getPicByUrl = new Runnable() { 44 @Override 45 public void run() { 46 String picturepath = edtUrl.getText().toString(); 47 try { 48 bmp = GetImgUtil.getImage(picturepath);// BitmapFactory:图片工厂! 49 sendMsg(0); 50 } catch (Exception e) { 51 Log.i("ggggg", e.getMessage()); 52 sendMsg(1); 53 } 54 } 57 }; 58 59 private void sendMsg(int i) { 60 Message msg = new Message(); 61 msg.what = i; 62 handler.sendMessage(msg); 63 } 64 @SuppressLint("HandlerLeak") 65 public Handler handler = new Handler() { 66 @Override 67 public void handleMessage(Message msg) { 68 if (msg.what == 0) { 69 imgPic.setImageBitmap(bmp); 70 }else if(msg.what == 1){ 71 Toast.makeText(getApplicationContext(), "获取图片错误", Toast.LENGTH_SHORT).show(); 72 } 73 } 74 }; 75 76 @Override 77 public boolean onCreateOptionsMenu(Menu menu) { 78 // Inflate the menu; this adds items to the action bar if it is present. 79 getMenuInflater().inflate(R.menu.picture, menu); 80 return true; 81 } 82 83 }
1 import java.io.InputStream; 2 import java.net.HttpURLConnection; 3 import java.net.URL; 4 import android.graphics.Bitmap; 5 import android.graphics.BitmapFactory; 6 7 public class GetImgUtil { 8 // 获取网络图片的数据 9 public static Bitmap getImage(String picturepath) { 10 URL myFileURL; 11 Bitmap bitmap=null; 12 try{ 13 myFileURL = new URL(picturepath); 14 //获得连接 15 HttpURLConnection conn=(HttpURLConnection)myFileURL.openConnection(); 16 //设置超时时间为5秒,conn.setConnectionTiem(0);表示没有时间限制 17 conn.setConnectTimeout(5*1000); 18 //连接设置获得数据流 19 conn.setDoInput(true); 20 //不使用缓存 21 conn.setUseCaches(false); 22 //这句可有可无,没有影响 23 //conn.connect(); 24 //得到数据流 25 InputStream is = conn.getInputStream(); 26 //解析得到图片 27 bitmap = BitmapFactory.decodeStream(is); 28 //关闭数据流 29 is.close(); 30 }catch(Exception e){ 31 e.printStackTrace(); 32 } 33 34 return bitmap; 35 } 36 }
Android中图片处理存在的难点: OOM内存溢出; 图片尺寸和缩略图处理的平衡; 网络图片的加载与缓存机制;
这里将会选择两款比较优秀的开源图片处理库框架:
Universal-ImageLoader和Picasso为大家进行讲解。
Universal-ImageLoader的简介和特点: Universal-ImageLoader是目前Android主流的图片处理库框架之一,作者是白俄罗斯的。
Sergey Tarasevich。
在Android图片处理中需要考虑的问题很多,例如OOM、图片缓存和网络图片加载、多线程问题及图片压缩处理等等复杂的问题。但是Universal-ImageLoader已经帮我们把这些问题处理好了,对外提供了相应的完善的请求API,我们只需要按照要求使用即可。
Universal-ImageLoader特点:
# 支持本地图片和网络图片的多线程异步加载和缓存处理;
# 个性化的配置自己项目的ImageLoader;
# 图片加载过程的监听回调;
# 自动对加载的图片针对当前剩余内存进行裁剪优化,防止OOM;
# 较好的控制图片的加载过程,例如暂停图片加载,重新开始加载图片;
缺点:没有对本地文件压缩处理的相关API方法以及默认都是Src模式设置图片,没有针对Background属性开放API。
Picasso的简介和特点
Picasso是Square公司开源的一个Android图形缓存库。可以实现图片下载和缓存功能。
特点:
加载载网络或本地图片并自动缓存处理;
链式调用;
图形转换操作,如变换大小,旋转等,提供了接口来让用户可以自定义转换操作;
在Adapter中回收和取消当前的下载功能.
总结:
都有高效的网络图片下载和缓存性能
Universal-ImageLoader功能多,灵活使用配置
Picasso使用复杂的图片压缩转换来尽可能的减少内存消耗
在Adapter中需要取消已经不在视野范围的ImageView图片资源的加载,否则会导致图片错位,Picasso已经解决了这个问题。
【Universal-ImageLoader 的用法和案例】
Universal-ImageLoader的配置; 用Universal-ImageLoader加载网络图片和本地图片;
可以全局配置:在Application里进行配置。 可以针对单一加载图片的地方配置。
例如:可配置图片缓存保存路径、线程池内加载的数量、缓存的文件数量 、每个缓存文件的最大长宽、加载过程中和加载失败时显示的图片等等。
Universal-ImageLoader支持网络图片的加载和本地图片的加载,而且可以自动缓存、自动根据当前手机环境进行压缩处理防止出现OOM。
也可以监听整个图片的加载过程,可控。
3 import java.io.File;
4
5 import android.app.Application;
6 import android.graphics.Bitmap;
7 import android.os.Environment;
8
9 import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache;
10 import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
11 import com.nostra13.universalimageloader.cache.memory.impl.UsingFreqLimitedMemoryCache;
12 import com.nostra13.universalimageloader.core.DisplayImageOptions;
13 import com.nostra13.universalimageloader.core.ImageLoader;
14 import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
15 import com.nostra13.universalimageloader.core.assist.ImageScaleType;
16 import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
17 import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
18 import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer;
19 import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
20
21 public class MyApplication extends Application {
22 @Override
23 public void onCreate() {
24 // TODO Auto-generated method stub
25 super.onCreate();
26 ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
27 this)
28 .memoryCacheExtraOptions(480, 800)
29 // max width, max height,即保存的每个缓存文件的最大长宽
30 .discCacheExtraOptions(480, 800, null)
31 // Can slow ImageLoader, use it carefully (Better don't use
32 // it)/设置缓存的详细信息,最好不要设置这个
33 .threadPoolSize(3)
34 // 线程池内加载的数量
35 .threadPriority(Thread.NORM_PRIORITY - 2)
36 .denyCacheImageMultipleSizesInMemory()
37 .memoryCache(new UsingFreqLimitedMemoryCache(2 * 1024 * 1024))
38 // You can pass your own memory cache
39 // implementation/你可以通过自己的内存缓存实现
40 .memoryCacheSize(2 * 1024 * 1024)
41 .discCacheSize(50 * 1024 * 1024)
42 .discCacheFileNameGenerator(new Md5FileNameGenerator())
43 // 将保存的时候的URI名称用MD5 加密
44 .tasksProcessingOrder(QueueProcessingType.LIFO)
45 .discCacheFileCount(100)
46 // 缓存的文件数量
47 .discCache(
48 new UnlimitedDiscCache(new File(Environment
49 .getExternalStorageDirectory()
50 + "/myApp/imgCache")))
51 // 自定义缓存路径
52 .defaultDisplayImageOptions(getDisplayOptions())
53 .imageDownloader(
54 new BaseImageDownloader(this, 5 * 1000, 30 * 1000))
55 .writeDebugLogs() // Remove for release app
56 .build();// 开始构建
57 ImageLoader.getInstance().init(config);
58 }
59
60 private DisplayImageOptions getDisplayOptions() {
61 DisplayImageOptions options;
62 options = new DisplayImageOptions.Builder()
63 .showImageOnLoading(R.drawable.ic_launcher) // 设置图片在下载期间显示的图片
64 .showImageForEmptyUri(R.drawable.ic_launcher)// 设置图片Uri为空或是错误的时候显示的图片
65 .showImageOnFail(R.drawable.ic_launcher) // 设置图片加载/解码过程中错误时候显示的图片
66 .cacheInMemory(true)// 设置下载的图片是否缓存在内存中
67 .cacheOnDisc(true)// 设置下载的图片是否缓存在SD卡中
68 .considerExifParams(true) // 是否考虑JPEG图像EXIF参数(旋转,翻转)
69 .imageScaleType(ImageScaleType.EXACTLY_STRETCHED)// 设置图片以如何的编码方式显示
70 .bitmapConfig(Bitmap.Config.RGB_565)// 设置图片的解码类型//
71 // .delayBeforeLoading(int delayInMillis)//int
72 // delayInMillis为你设置的下载前的延迟时间
73 // 设置图片加入缓存前,对bitmap进行设置
74 // .preProcessor(BitmapProcessor preProcessor)
75 .resetViewBeforeLoading(true)// 设置图片在下载前是否重置,复位
76 .displayer(new RoundedBitmapDisplayer(20))// 是否设置为圆角,弧度为多少
77 .displayer(new FadeInBitmapDisplayer(100))// 是否图片加载好后渐入的动画时间
78 .build();// 构建完成
79 return options;
80 }
81 }
1 import android.app.Activity; 2 import android.graphics.Bitmap; 3 import android.os.Bundle; 4 import android.util.Log; 5 import android.view.View; 6 import android.widget.ImageView; 7 8 import com.nostra13.universalimageloader.core.ImageLoader; 9 import com.nostra13.universalimageloader.core.assist.FailReason; 10 import com.nostra13.universalimageloader.core.listener.ImageLoadingListener; 11 12 /** 13 * 1、 Universal-ImageLoader的配置 14 * 15 * 2、用Universal-ImageLoader加载网络图片和本地图片 16 */ 17 public class MainActivity extends Activity { 18 private ImageLoader loader; 19 private ImageView iv_img; 20 21 @Override 22 protected void onCreate(Bundle savedInstanceState) { 23 super.onCreate(savedInstanceState); 24 setContentView(R.layout.activity_main); 25 26 loader = ImageLoader.getInstance(); 27 28 iv_img = (ImageView) this.findViewById(R.id.iv_img); 29 String uri = "file:///" + "本地路径"; 30 // loader.displayImage( 31 // "http://s1.jikexueyuan.com/current/static/images/logo.png", 32 // iv_img); 33 loader.displayImage( 34 "https://www.baidu.com/img/bd_logo1.png", 35 iv_img, new ImageLoadingListener() { 36 37 @Override 38 public void onLoadingStarted(String arg0, View arg1) { 39 Log.i("info", "onLoadingStarted"); 40 } 41 42 @Override 43 public void onLoadingFailed(String arg0, View arg1, 44 FailReason arg2) { 45 Log.i("info", "onLoadingFailed"); 46 } 47 48 @Override 49 public void onLoadingComplete(String arg0, View arg1, 50 Bitmap arg2) { 51 Log.i("info", "onLoadingComplete"); 52 } 53 54 @Override 55 public void onLoadingCancelled(String arg0, View arg1) { 56 Log.i("info", "onLoadingCancelled"); 57 } 58 }); 59 } 60 61 }
1 <uses-permission android:name="android.permission.INTERNET"/> 2 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> 3 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 4 5 <application 6 android:name="com.jike.imageloaderdemo.MyApplication" 7 android:allowBackup="true"> 11 <activity 12 ............... 19 </activity> 20 </application>
Picasso的用法和案例
主要介绍Async-http的用法,包含以下几个知识点:
Picasso的几个重要方法的介绍; 用Picasso加载网络图片和本地图片;
图片异步加载: Picasso.with(context).load("http://baidu.com/logo.png").into(imageView);
图片转换:转换图片以适应布局大小并减少内存占用
Picasso.with(context).load(url).resize(50, 50) .centerCrop() .into(imageView);
Adapter 中的下载:Adapter的重用会被自动检测到,Picasso会取消上次的加载 空白或者错误占位图片设置方法及本地资源文件的加载方法
Picasso采用链式调用加载和处理图片方式。 除了加载网络图片,picasso还支持加载Resources, assets, files, content providers中的本地资源文件。
1 import android.app.Activity; 2 import android.os.Bundle; 3 import android.widget.ImageView; 4 5 import com.squareup.picasso.Picasso; 6 7 /** 8 * 1、Picasso的几个重要方法的介绍 9 * 10 * 2、用Picasso加载网络图片和本地图片 11 */ 12 13 public class MainActivity extends Activity { 15 private ImageView iv_img; 16 17 @Override 18 protected void onCreate(Bundle savedInstanceState) { 19 super.onCreate(savedInstanceState); 20 21 setContentView(R.layout.activity_main); 22 23 iv_img = (ImageView) this.findViewById(R.id.iv_img); 24 Picasso.with(this) 25 .load("https://www.baidu.com/img/bd_logo1.png") 26 .into(iv_img); 27 Picasso.with(this) 28 .load("https://www.baidu.com/img/bd_logo1.png") 29 .resize(50, 50).into(iv_img); 30 Picasso.with(this) 31 .load("https://www.baidu.com/img/bd_logo1.png") 32 .error(R.drawable.ic_launcher).into(iv_img); 33 } 34 }
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>