先来一个普通的加载图片的方法。
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 @Override27 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 @Override36 public void onClick(View arg0) {37 //为了不造成阻塞,启动一个工作线程38 new Thread(getPicByUrl).start();39 }40 });41 }42 43 Runnable getPicByUrl = new Runnable() {44 @Override45 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 @Override67 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 @Override77 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 @Override23 public void onCreate() {24 // TODO Auto-generated method stub25 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 use32 // 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 cache39 // 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(Environment49 .getExternalStorageDirectory()50 + "/myApp/imgCache")))51 // 自定义缓存路径52 .defaultDisplayImageOptions(getDisplayOptions())53 .imageDownloader(54 new BaseImageDownloader(this, 5 * 1000, 30 * 1000))55 .writeDebugLogs() // Remove for release app56 .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)//int72 // 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 @Override22 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 @Override38 public void onLoadingStarted(String arg0, View arg1) {39 Log.i("info", "onLoadingStarted");40 }41 42 @Override43 public void onLoadingFailed(String arg0, View arg1,44 FailReason arg2) {45 Log.i("info", "onLoadingFailed");46 }47 48 @Override49 public void onLoadingComplete(String arg0, View arg1,50 Bitmap arg2) {51 Log.i("info", "onLoadingComplete");52 }53 54 @Override55 public void onLoadingCancelled(String arg0, View arg1) {56 Log.i("info", "onLoadingCancelled");57 }58 });59 }60 61 }
12 3 4 5 11 20
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 @Override18 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 }
DEMO下载: