Android 图片加载性能优化总结
Android图片内存优化的几点心得
1 BitmapFactory.Options options = new BitmapFactory.Options(); 2 options.inPreferredConfig = Bitmap.Config.ARGB_4444; 3 Bitmap img = BitmapFactory.decodeFile("/sdcard/1.png", options);
该段代码即是读取1.png的缩略图,长度、宽度都只有原图片的1/2。图片大小减少,占用的内存自然也变小了。这么做的弊端是图片质量变差,inSampleSize的值越大,图片的质量就越差。由于各手机厂商缩放图片的算法不同,在不同手机上的缩放图片质量可能会不同。笔者就遭遇过moto手机上图片缩放后质量可以接受,三星手机上同样的缩放比例,质量却差很多的情况。
4、使用Matrix对象放大的图片如何更改颜色模式:
虽然使用Matrix对象放大图片,必定会耗费更多的内存,但有时候也不得不这样做。放大后的图片使用的ARGB_8888颜色模式,就算原图片是ARGB_4444颜色模式也一样,而且没有办法在放大时直接指定颜色模式。可以采用以下办法更改图片颜色模式。
Matrix matrix = new Matrix(); float newWidth = 200;//图片放大后的宽度 float newHeight = 300;//图片放大后的长度 matrix.postScale(newWidth / img.getWidth(), newHeight/ img.getHeight()); Bitmap img1 = Bitmap.createBitmap(img, 0, 0, img.getWidth(), img.getHeight(), matrix, true);//得到放大的图片 img2 = img1.copy(Bitmap.Config.ARGB_4444, false);//得到ARGB_4444颜色模式的图片 img = null; img1 = null;
android 网络加载图片 对图片资源进行优化 并且实现内存双缓存 磁盘缓存
android 网络加载图片,对图片资源进行优化,并且实现内存双缓存+ 磁盘缓存经常会用到网络文件比如查看大图片数据资源优化的问题,当然用开源的项目 Android-Universal-Image-Loader 或者ignition 都是个很好的选择。
在这里把原来写过的优化的代码直接拿出来,经过测试千张图片效果还是不错的。
工程目录:至于Activity 就是加载了1个网格布局[java]view plaincopy1./**2. * 实现异步加载和 2级缓存3. */4.public class ImagedownActivity extends Activity {5.6.public static String filepath;7.@Override8.public void onCreate(Bundle savedInstanceState) {9.super.onCreate(savedInstanceState);10. setContentView(yout.main);11. filepath = this.getCacheDir().getAbsolutePath();12. GridView gv=(GridView)findViewById(R.id.gridview01);13.//设置列数14. gv.setNumColumns(3);15.//配置适配器16. gv.setAdapter(new Myadapter(this));17. }18.19.@Override20.protected void onDestroy() {21.// TODO Auto-generated method stub22.//activity 销毁时,清除缓存23. MyImageLoader.removeCache(filepath);24.super.onDestroy();25. }26.27.}接下来Myadapter.java(给网格每个item塞入图片)在生成每个item 异步请求网络获取image [java]view plaincopy1.public class Myadapter extends BaseAdapter {2.private Context context;3.private String root ="http://192.168.0.100:8080/Android_list/";4.private String[] URLS;5.private final MyImageLoader myImageLoader = new MyImageLoader(context);;6.7./**8. * adapter 初始化的时候早一堆数据9. * 这里我请求的是自己搭的服务器10. * @param context11. */12.public Myadapter(Context context){13.this.context =context;14. URLS = new String[999];15.for (int i = 0; i < 999; i++) {16. URLS[i] = root + (i+1)+".jpg";17. }18. }19.20.21.@Override22.public int getCount() {23.return URLS.length;24. }25.26.@Override27.public Object getItem(int position) {28.return URLS[position];29. }30.31.@Override32.public long getItemId(int position) {33.return URLS[position].hashCode();34. }35.36.37.38.@Override39.public View getView(int position, View view, ViewGroup parent) {40. ImageView imageView;41.if(view==null){42. imageView=new ImageView(context);43. imageView.setLayoutParams(new youtParams(200,190));44. imageView.setAdjustViewBounds(false);45. imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);46. imageView.setPadding(5, 5, 5, 5);47. }else{48. imageView=(ImageView)view;49. }50. myImageLoader.downLoad(URLS[position], (ImageView)imageView , context);51.return imageView;52. }53.}MyImageLoader.java[java]view plaincopy1.public class MyImageLoader {2.3.//最大内存4.final static int memClass = (int) Runtime.getRuntime().maxMemory();5.private Context context;6.7.// 是否缓存到硬盘8.private boolean diskcache = true;9.10.// 定义一级缓存的图片数11.private static final int catch_num = 10;12.13.// 定义二级缓存容器软引用14.private static ConcurrentHashMap<String, SoftReference<Bitmap>> current_hashmap = new ConcurrentHashMap<String, SoftReference<Bitmap>>();15.16.// 定义一级缓存容器强引用 (catch_num ,0.75f,true)默认参数2.加载因子默认3.排序模式 true17.private static LinkedHashMap<String, Bitmap> link_hashmap = new LinkedHashMap<String, Bitmap>(catch_num ,0.75f,true) {18.19.// 必须实现的方法20.protected boolean removeEldestEntry(java.util.Map.Entry<String, Bitmap> eldest) {21./** 当一级缓存中图片数量大于定义的数量放入二级缓存中22. */23.if (this.size() > catch_num) {24.// 软连接的方法存进二级缓存中25. current_hashmap.put(eldest.getKey(), new SoftReference<Bitmap>(26. eldest.getValue()));27.//缓存到本地28. cancheToDisk(eldest.getKey(),eldest.getValue() );29.30.return true;31. }32.return false;33. };34. };35.36.public MyImageLoader(Context context) {37.38. }39.40.41./**42. * 外部调用此方法进行下载图片43. */44.public void downLoad(String key , ImageView imageView,Context context){45.// 先从缓存中找。
Android开发中的性能优化技巧和最佳实践(二)
Android开发中的性能优化技巧和最佳实践近年来,移动设备的普及使得Android平台的应用开发变得越来越受欢迎。
然而,伴随着应用数量的爆炸增长,用户对应用性能的要求也越来越高。
因此,Android开发者需要采取一些性能优化技巧和最佳实践,来提升应用的性能和用户体验。
I. 启动时间优化应用的启动时间是用户首次接触应用的重要指标。
为了缩短启动时间,开发者可以采取以下几种优化技巧:1. 延迟初始化:延迟初始化是指将某些资源的加载推迟到真正需要使用的时候。
这样可以避免在应用启动时加载过多的资源,从而提升启动速度。
2. 异步加载:将耗时的初始化操作放在后台线程进行,以保持主线程的响应性。
可以使用AsyncTask或者ThreadPoolExecutor等工具来实现异步加载。
3. 冷启动优化:冷启动是指应用从完全关闭状态重新启动的过程。
在冷启动过程中,系统会执行一系列初始化操作,因此耗时较长。
为了缩短冷启动时间,开发者可以采取预加载、缓存等策略。
例如,可以在应用启动时预加载常用的数据或者界面,以减少后续启动时的初始化时间。
II. 内存管理和优化Android平台的内存管理相对复杂,合理的内存管理对于应用的性能和稳定性至关重要。
以下是一些内存优化的技巧和最佳实践:1. 使用内存分析工具:Android Studio提供了内存监测和分析工具,例如Memory Profiler和Allocation Tracker。
开发者可以利用这些工具找出内存泄漏和冗余对象,并进行修复和优化。
2. 避免过度绘制:过度绘制是指在绘制过程中,多次绘制同一区域导致性能下降。
可以通过减少视图层级、使用ViewStub延迟加载视图等方式来减少过度绘制。
3. 优化图片加载:图片加载是Android应用中常见的性能瓶颈之一。
开发者可以通过使用Glide、Picasso等图片加载库来优化图片加载,并采用适当的压缩算法减少图片大小。
III. 网络请求优化在移动应用中,网络请求往往是性能瓶颈之一。
客户端开发技巧:优化应用的图片加载(七)
客户端开发技巧:优化应用的图片加载在移动应用开发中,图片加载是一个不可忽视的重要环节。
过分依赖网络加载的图片可能会导致用户体验下降,长时间的加载等待让用户感到烦躁。
本文将介绍一些优化应用图片加载的技巧,提升应用性能和用户满意度。
1. 选择合适的图片格式图片格式的选择直接影响了图片加载速度和应用性能。
通常情况下,JPEG格式适用于色彩丰富的照片,而PNG格式适用于透明背景或者颜色简单的图标。
根据实际需求,合理选择图片格式可以节约带宽和提高加载速度。
2. 压缩图片大小过大的图片会占用过多的网络带宽和手机存储空间,同时加载速度也会变慢。
在应用开发中,我们可以使用图片压缩工具来减小图片的尺寸和文件大小,例如TinyPNG、JPEGmini等。
另外,还可以利用图片编辑工具手动调整图片的质量和尺寸,以达到更好的加载效果。
3. 图片缓存图片缓存是提高应用加载速度的有效手段之一。
在网络加载图片时,将加载过的图片缓存在本地,下次再次加载时直接读取本地缓存,避免重复下载。
常用的图片缓存库有Picasso、Glide等,它们提供了丰富的缓存策略和高效的异步加载机制。
4. 懒加载技术对于需要滚动加载的图片列表,一次性加载所有图片会占用大量的内存和带宽。
为了提高用户体验,可以采用懒加载技术,即在滚动到特定位置时再加载图片。
通过监听滚动事件,及时释放不可见区域的图片资源,可以有效减少内存占用和加快列表加载速度。
5. 图片预加载在应用启动时,预加载即将使用到的图片资源,可以缩短用户的等待时间和提升应用的整体响应速度。
可以通过异步线程预加载图片,并将加载好的图片缓存在内存中,以备后续使用。
图片预加载可以使用第三方库如Fresco、Universal Image Loader等来实现。
6. 图片延迟加载对于需要优先显示其他内容的界面,可以将图片的加载延迟到用户获取其他重要信息之后。
通过异步加载图片的方式,用户可以先看到页面的基本结构和内容,而无需等待图片加载完成。
AndroidFresco图片加载优化的方案
AndroidFresco图⽚加载优化的⽅案⽬录优化背景数据记录优化⽅案注意事项优化背景⼀般情况下,Fresco图⽚加载需使⽤SimpleDraweeView,这个控件并不能⾃动根据⾃⾝的尺⼨按需加载图⽚,即⼀个 N×N 的UI控件,背后加载的实际图⽚可能是 2N×2N。
这就导致了实际应⽤运⾏过程中的内存使⽤效率不⾼,需要针对其进⾏内存优化。
在⼀些⼊门级硬件设备上,表现得尤为明显,随着程序的运⾏时间的增长,OOM的风险也不断加⼤。
Fresco版本:1.13.0数据记录声明控件⼤⼩为 480×270<com.facebook.drawee.view.SimpleDraweeViewandroid:id="@+id/simple_drawee_view"android:layout_width="480dp"android:layout_height="270dp"android:layout_alignParentBottom="true"android:layout_centerHorizontal="true"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" />加载图⽚代码,调⽤Fresco的setImageURIval mImageUrl = "https:///images/demo/demo4.jpg"val simple_drawee_view = findViewById<SimpleDraweeView>(R.id.simple_drawee_view)simple_drawee_view.setImageURI(mImageUrl)运⾏后dump内存如下,可以发现内存中的图⽚尺⼨为1920×1080,即此时SimpleDraweeView会按照⽹络上的原图尺⼨进⾏加载,内存占⽤⼤⼩为 8294475Bytes = 7.91Mb。
Android开发中的性能优化技巧和最佳实践(三)
Android开发中的性能优化技巧和最佳实践1. 背景介绍随着智能手机的快速普及,Android应用程序的开发变得越来越重要。
然而,随着应用程序复杂性的增加,性能问题成为了开发者们需要解决的重要挑战。
本文将探讨一些Android开发中的性能优化技巧和最佳实践。
2. 布局优化在开发Android应用时,良好的布局设计是关键。
使用嵌套布局可能会导致冗余的视图层次结构,从而影响应用程序的性能。
因此,推荐使用ConstraintLayout等更高效的布局容器,并避免嵌套过深。
另外,使用布局预加载和重用视图(如RecyclerView)也可以提高性能。
3. 图片处理图片加载是Android应用中常见的性能瓶颈之一。
为了优化图片加载,可以采取多种策略。
首先,根据不同的屏幕密度提供适当的图片资源,避免不必要的缩放。
其次,使用图片压缩工具(如TinyPNG)减小图片的文件大小。
最后,使用内存缓存和磁盘缓存来避免重复加载图片。
4. 内存管理合理管理内存是提高Android应用性能的关键。
使用LeakCanary等内存泄漏检测工具来及时发现和修复内存泄漏问题。
另外,注意避免在主线程执行耗时操作,以免引起ANR(Application Not Responding)问题。
推荐使用AsyncTask或线程池来处理耗时操作,并在必要时使用Handler来更新UI。
5. 数据库优化对于需要大量数据库操作的应用,合理优化数据库访问是很重要的。
使用索引和合适的数据结构(如B树)可以加快查询速度。
此外,使用批量插入和更新操作可以减少数据库访问的次数,从而提高性能。
6. 网络通信在进行网络通信时,优化网络请求可以减少应用的响应时间。
避免频繁的网络请求,尽可能合并请求或使用缓存。
另外,使用gzip等压缩算法来减小传输数据的大小也是一种有效的优化策略。
7. 多线程处理在Android开发中,合理使用多线程可以提高应用的响应速度和用户体验。
AndroidListview加载图片优化
AndroidListview加载图片优化关于ListView异步加载图片有很多方式,此篇文章讲讲本地加载大量图片时出现的卡顿现象怎么优化;应当坚持这么一条原则:把用户的体验放在第一位,用户能看到的,触摸到的始终放在第一时间解决所以有这样的思路:1.监听Listview的scroll状态,1)如果内存中有用户要看到的图片,则加载2)内存中没有用户要看到的图片,则根据scroll状态来加载a.scroll 为停止则开始加载图片到内存,更新界面b.scroll 滑动或者快速滑动则不加载图片到内存,取而代之的是添加默认图片3)如果根本就没有用户想看的图片,则不用加载图片到内存,直接加载默认图片2.与之同时,主线程已开启的时候就开启一个子线程加载用户要看到的所有图片到内存中去(完成之后更新界面,未完成时每次scroll停止的时候也会更新界面所以不会影响用户的交互)贴部分代码:[java]view plaincopy1.public class ContactsListViewAdapter extends BaseAdapt er {2.private LayoutInflater inflater;3.private ArrayList<ContactDataBean> contactList;4.private int mLayoutRes;5.private Context mContext;6.private ListView lv;7.private int scrollStauts=0;8.9.public ContactsListViewAdapter(Context context, int layo utRes, ArrayList<ContactDataBean> contactList, ListView lv) {10.this.contactList = contactList;11.this.inflater = LayoutInflater.from(context);12.this.mContext = context;13.this.mLayoutRes = layoutRes;14.this.lv = lv;15.this.lv.setOnScrollListener(new AbsListView.OnScrollLis tener() {16.17.@Override18.public void onScrollStateChanged(AbsListView view, in t scrollState) {19.// TODO Auto-generated method stub20.switch (scrollState) {21.case AbsListView.OnScrollListener.SCROLL_STATE_IDLE: //停止 022.scrollStauts=0;23.updateUI();24.//System.out.println("停止");25.break;26.case AbsListView.OnScrollListener.SCROLL_STATE_TOU CH_SCROLL://触摸滑动 127.scrollStauts=1;28.29.//System.out.println("触摸滑动");30.break;31.case AbsListView.OnScrollListener.SCROLL_STATE_FLIN G://快速滑动 232.scrollStauts=2;33.//System.out.println("快速滑动");34.break;35.default:36.break;37.}38.}39.40.@Override41.public void onScroll(AbsListView view, int firstVisibleIt em, int visibleItemCount, int totalItemCount) {42.}43.});44.}45.46.public void updateUI() {47.this.notifyDataSetChanged();48.}49.public void setListData(ArrayList<ContactDataBean> c ontactList) {50.this.contactList = contactList;51.}52.53.public void updateDate() {54.this.notifyDataSetChanged();55.}56.57.@Override58.public int getCount() {59.return contactList.size();60.}61.62.@Override63.public Object getItem(int position) {64.return contactList.get(position);65.}66.67.@Override68.public long getItemId(int position) {69.return contactList.get(position).hashCode();70.}71.72.@Override73.public View getView(int position, View convertView, Vi ewGroup arg2) {74.ViewHolder holder = null;75.if (convertView == null) {76.holder = new ViewHolder();77.convertView = inflater.inflate(mLayoutRes, null); = (TextView) convertView.findViewById(R. id.contact_name);79.holder.image = (ImageView) convertView.findViewByI d(R.id.contact_image);80.convertView.setTag(holder);81.} else {82.holder = (ViewHolder) convertView.getTag();83.}84.ContactDataBean cdb = contactList.get(position);.setText(cdb.displayName);86.if (cdb.photo != null) {// 内存中有头像87.holder.image.setImageBitmap(cdb.photo);88.} else if (cdb.photo_id > 0) {// 实际有头像,但头像还没有加载到内存89.if(scrollStauts==0){90.Uri contactImageUri = ContentUris.withAppendedId(C ontactsContract.Contacts.CONTENT_URI, cdb.contact_id);91.InputStream in = ContactsContract.Contacts.openCont actPhotoInputStream(mContext.getContentResolver(), contactI mageUri);92.cdb.photo = BitmapFactory.decodeStream(in);93.holder.image.setImageBitmap(cdb.photo);94.try {95.in.close();96.} catch (IOException e) {97. e.printStackTrace();98.}99.}else {100.holder.image.setImageResource(R.drawable.call_log_c ontact_default);101.}102.} else {// 没有头像,设置默认头像103.holder.image.setImageResource(R.drawable.call_log_c ontact_default);104.}105.return convertView;106.}107.108.private class ViewHolder {109.ImageView image;110.TextView name;111.}112. 113.}。
移动端性能优化技巧总结
移动端性能优化技巧总结随着移动互联网的发展,移动端应用已经成为人们生活的重要组成部分。
然而,移动端应用的性能问题也越来越凸显,如加载时间慢、内存占用高以及耗电量大等问题,给用户的使用体验带来了很大不便。
因此针对移动端的性能优化就成为了一项需要解决的重要问题。
本文将从app优化、H5优化、JS/CSS文件优化、图片优化、代码优化以及缓存优化等六个方面分享与移动端性能优化相关的技巧。
一、app优化1.采用本地存储方式当应用启动时,可以对一些静态数据进行本地缓存。
这样可以减少网络请求,缩短应用启动时间。
同时,可以运用操作系统提供的本地存储方式,将数据缓存到用户的本地或者SD卡上,从而提高数据加载速度和用户体验。
2.页面懒加载通过将页面上的资源划分成多个区域,在用户滑动页面时根据需要才进行加载,可以减少页面加载时间,提高页面响应速度。
二、H5优化1.减少HTTP请求数量HTTP请求数量过多会导致加载时间过长,从而影响页面的响应速度。
因此,可以将多个JS或CSS文件合并为一个文件,或将多个小的图片合并为一张雪碧图。
2.压缩文件大小可以使用GZIP将文件压缩成更小的大小,以减少网络传输时间。
同时,对JS和CSS文件采用混淆和精简处理,可以有效减小文件的体积。
三、JS/CSS文件优化1.加上版本号在发布新版本时,可以给每个静态文件加上一个版本号。
这样能够避免浏览器缓存文件的弊端,让用户能够及时得到最新的静态文件。
2.尽量减少JS和CSS文件的数量减少JS和CSS文件的数量,可以减少HTTP请求,缩短文件传输时间。
四、图片优化1.选择正确的图片格式对于一些色彩简单的图片,可以选择GIF格式。
对于一些颜色丰富的图片,可以选择JPEG格式。
而对于需要透明背景的图片,则应该选择PNG格式。
选择正确的图片格式,能够最大化地减少图片的体积。
2.缩小图片的尺寸对于非必须的图片,可以通过缩小图片的尺寸,以减小图片的大小。
同时,可以使用工具对图片进行压缩。
移动应用开发中的图片处理与优化技巧
移动应用开发中的图片处理与优化技巧随着移动设备的普及和高清屏幕的应用,图片在移动应用中的重要性愈发凸显。
在移动应用开发中,如何合理地处理和优化图片,不仅能提升用户体验,还能减少应用的内存占用和加载时间,对于开发者来说是一个重要的任务。
本文将介绍一些常用的图片处理与优化技巧,帮助开发者提升移动应用的性能和用户体验。
1. 图片格式选择在移动应用开发中,常见的图片格式有JPEG、PNG和WebP。
对于照片、复杂的图像以及需要透明度的图像,JPEG是较好的选择;而对于图标、背景、扁平化设计等,PNG格式通常会更加适合。
WebP是一种兼容性较好且具有较高压缩率的图片格式,可以用于在Android应用中替代JPEG和PNG。
2. 图片尺寸调整在移动应用中,图片的尺寸往往比实际展示的尺寸要大,为了减少应用的内存占用和加载时间,开发者可以根据实际需求调整图片的尺寸。
API提供了强大的功能,可以在应用运行时根据设备的屏幕密度来加载相应尺寸的图片,这样可以确保在不同设备上显示的图片效果均衡。
另外,在图片资源被打包到应用中时,也可以使用工具进行批量调整尺寸,减少应用的体积。
3. 图片压缩图片的压缩是移动应用开发中不可避免的一个环节。
开发者可以使用图片编辑软件,如Photoshop、Sketch等,对图片进行压缩。
另外,也可以使用开源的图片压缩工具,如TinyPNG、JPEGmini等,它们能够有效地减少图片的文件大小而又不影响图片的视觉质量。
压缩后的图片可以减少应用占用的存储空间、减少网络传输的流量,并加快图片的加载速度。
4. 图片懒加载在移动应用中,不同页面上可能会包含大量的图片资源。
为了提高页面加载速度,开发者可以使用图片懒加载技术。
图片懒加载指的是当用户滚动到页面中可见的区域时,再加载图片资源,而不是一次性加载所有图片。
这种延迟加载的方式可以减少首次打开应用时的加载时间,并提升用户体验。
5. 图片缓存图片缓存是移动应用中提高用户体验和减少数据流量的有效手段。
Android中高效的显示图片 - 加载大图
Android中高效的显示图片 - 加载大图Android开发者应该对上面这个错误都不陌生。
Android系统对每个应用使用的内存是有限制的,一旦应用使用的总内存超过这个阀值,系统就会抛出上面的错误导致应用crash。
内存溢出的错误是开发者必须要解决的,根据经验来说,内存溢出很多场景都是由图片资源使用不当引起的。
Android官方的开发者文档中也有专门的文章来介绍这个问题。
高效的加载高分辨率的图片我们以加载Galaxy Nexus拍摄的照片为例。
500万的摄像头拍摄的照片分辨率为2592x1936像素,如果我们使用ARGB_8888设置(android 2.3以后的默认设置,这种设置规定用四个字节来存储一个像素值)来加载这张图片,它将占用19M的内存(2592*1936*4字节)。
在某些限制每个应用最多使用16M内存的手机上,这一张图片就会导致内存溢出。
出现这种情况怎么办呢?冷静分析我们会发现在手机上展示图片时我们并不需要这么高分辨率的图片。
比如在屏幕分辨率为1920x1080的手机上,即使你要展示图片的imageview充满了整个屏幕,也最多需要1920x1080的图片,更高分辨率的图片对我们的展示效果并没有提升,只会白白浪费我们宝贵的内存空间。
所以对这种加载高分辨率的图片情况我们应该加载一个低分辨率版本的图片到内存中。
接下来我们看下具体的操作步骤。
加载图片尺寸和类型针对不同的图片数据来源,BitmapFactory提供了不同的解码方法(decodeResource()、decodeFile()...),这些方法在构造图片的时候会申请相应的内存空间,所以它们经常抛出内存溢出的异常。
这些方法都允许传入一个BitmapFactory.Options类型的参数来获取将要构建的图片的属性。
如果将inJustDecodeBounds的值设置成true,这些方法将不会真正的创建图片,也就不会占用内存,它们的返回值将会是空。
移动应用开发技术图片加载优化方法
移动应用开发技术图片加载优化方法移动应用开发技术:图片加载优化方法在移动应用开发中,图片加载是一个常见且重要的问题。
由于移动设备的屏幕尺寸和网络环境的不同,如何高效、快速地加载图片成为了开发者们需要面对的挑战。
本文将介绍一些优化图片加载的方法,帮助开发者提升应用的用户体验。
一、合理选择图片格式在移动应用中,选择合适的图片格式对于加载速度和清晰度都有很大影响。
最常见的图片格式有JPEG、PNG和WebP。
1. JPEG:适合展示大量颜色丰富的照片,具有较小的文件大小。
但是JPEG图片不支持透明度,且压缩会带来一定的失真。
2. PNG:支持透明度,适合加载简单图标和透明背景的图片。
但是PNG图片相对JPEG文件较大,加载速度会慢一些。
3. WebP:由Google开发的一种新型图片格式,支持无损和有损压缩,文件大小通常比JPEG和PNG更小,同时保持较高的画质。
但是WebP格式相对较新,部分设备和浏览器可能不兼容。
根据实际需求,开发者可以选择不同的图片格式,平衡图片质量和加载速度。
二、适当裁剪和压缩图片不同屏幕尺寸的设备需要展示不同尺寸的图片。
通过裁剪和压缩图片,可以减少加载时间和占用空间。
1. 裁剪图片:根据目标屏幕尺寸,将图片裁剪为合适的大小,避免在加载时进行额外的缩放操作。
举个例子,如果应用中需要展示一个100x100像素的头像,那么开发者可以在服务器端将头像图片裁剪为100x100像素,这样可以减少设备端的网络请求和处理时间。
2. 压缩图片:使用图片压缩算法来减小图片的文件大小。
常见的图片压缩算法有JPEG压缩和PNG压缩。
可以通过工具软件或在线网站将原始图片压缩为较小的文件大小,以减少下载时间和存储空间。
三、使用图片缓存技术图片缓存是一种常用的优化图片加载的方式,可以将已经下载的图片缓存在设备本地,提高图片的展示速度。
1. 内存缓存:通过内存缓存技术,将图片加载到内存中,避免重复加载。
开发者可以使用一些开源的图片缓存库,如Glide和Picasso,来实现内存缓存的功能。
移动应用开发技术中的图片优化与加载速度改进
移动应用开发技术中的图片优化与加载速度改进随着智能手机的普及,移动应用开发越来越受到关注。
而在移动应用的开发过程中,图片的优化和加载速度的改进是一个不可忽视的问题。
在本文中,我们将讨论一些图片优化的技术,并介绍如何改进图片的加载速度。
1. 图片优化技术在移动应用中,图片通常占据了很大的空间,因此优化图片的大小和质量是减少应用大小和提高加载速度的关键。
以下是一些常用的图片优化技术:a. 压缩图片大小:通过压缩图片的分辨率和像素密度,可以显著减少图片的文件大小。
可以使用一些图片压缩工具来实现,如TinyPNG和ImageOptim。
b. 选择合适的图片格式:在选择图片格式时,应考虑图片内容和需求。
JPEG 格式适合保存照片和复杂的图像,而PNG格式适合保存透明背景和文本图像。
同时,WebP格式也是一种支持有损和无损压缩的新型图片格式。
c. 使用矢量图形:矢量图形是由数学方程定义的图形,而不是由像素组成的。
由于矢量图形可以无损缩放,并且文件大小较小,因此在移动应用中使用矢量图形可以有效减少资源消耗。
2. 图片加载速度的改进图片的加载速度对于提高用户体验至关重要。
以下是一些改进图片加载速度的方法:a. 图片懒加载:图片懒加载是指在用户滚动屏幕或浏览网页时,仅加载可见区域的图片,而不加载其他区域的图片。
这样可以减少不必要的网络请求和加快页面加载速度。
b. 图片预加载:图片预加载是指在用户访问页面之前,提前加载将要使用的图片。
这样可以避免用户看到空白的图片或加载过程中的闪烁。
c. CDN加速:CDN(内容分发网络)是一种将静态资源部署到全球不同位置的技术,通过就近访问节点,加速图片的传输和加载。
使用CDN可以提高图片加载速度并减少服务器负载。
d. 图片缓存:图片缓存是指将已加载的图片保存在用户设备的缓存中,将来再次访问时可以直接从缓存中读取。
这样可以减少网络请求和加快图片加载速度。
总结在移动应用开发中,图片优化和加载速度的改进是重要的技术之一。
Android开发中的性能优化技巧和最佳实践(四)
Android开发中的性能优化技巧和最佳实践在如今移动互联网的时代,Android作为最流行的移动操作系统,拥有着庞大的用户群体。
然而,随着手机硬件的不断升级,用户对于应用性能的要求也日益提高。
因此,在Android开发过程中,性能优化是非常重要的一环。
本文将从多个方面介绍一些性能优化的技巧和最佳实践。
一、布局优化在Android应用开发中,布局是非常常见的一部分。
然而,不合理的布局会导致应用界面加载缓慢、卡顿等问题。
因此,进行布局优化是非常必要的。
首先,要避免过于复杂的布局结构。
过多的嵌套和层级会导致测量和绘制的开销增加。
可以尝试使用ConstraintLayout等新的布局方式来简化布局结构。
其次,对于需要重复使用的布局元素,可以考虑使用include和merge标签进行复用。
这样可以避免重复编写相同的布局代码,减小布局文件的大小。
另外,对于需要频繁更新的布局,可以使用RecyclerView代替ListView,通过ViewHolder的复用机制来提高性能。
二、图片优化在Android应用中,图片是占据大量资源的一部分。
因此,对于图片的处理和加载也是性能优化的重点。
首先,要避免加载过大的图片。
可以根据屏幕尺寸和显示需求来选择不同大小的图片资源,避免加载过多的像素。
其次,可以考虑使用JPEG格式的图片,因为JPEG格式的压缩比较高效。
同时,可以采用Android提供的图片压缩工具,如WebP或者PNG等,来减小图片资源的大小。
另外,对于需要频繁加载的图片,可以使用图片缓存技术来提高加载速度。
可以使用Android内置的LruCache或者第三方库如Glide来实现图片缓存。
三、内存优化Android应用在运行过程中会消耗大量的内存资源,合理管理内存可以提高应用的性能和稳定性。
首先,要注意避免内存泄漏。
在Android中,内存泄漏的情况非常常见,如未关闭的流、未释放的资源等。
因此,在编写代码时要注意及时释放内存,合理使用相关资源。
androidapp性能优化大汇总
androidapp性能优化⼤汇总 这⾥根据⽹络上各位⼤神已经总结的知识内容做⼀个⼤汇总,作为记录,⽅便后续“温故知新”。
性能指标:(1)使⽤流畅度: 图⽚处理器每秒刷新的帧数(FPS),可⽤来指⽰页⾯是否平滑的渲染。
⾼的帧率可以得到更流畅,更逼真的动画,不过帧率达到60fps以上,⼈眼主观感受到的差别就不⼤了。
所以以60fps作为衡量标准,即要求每⼀帧刷新的时间⼩于16ms,这样才能保证滑动中平滑的流畅度。
(2)内存使⽤情况: 在android系统中,每个APP进程除了同其他进程共享(shared dirty)外,还独⽤私有内存(private dirty),通常我们使⽤PSS(=私有内存+⽐例分配共享内存)来衡量⼀个APP的内存开销。
移动设备的内存资源是⾮常有限,为每个APP进程分配的私有内存也是有限制。
⼀⽅⾯我们要合理的申请内存使⽤,以免导致频繁的GC影响性能和⼤对象申请发⽣内存溢出;另⼀⽅⾯,我们要及时释放内存,以免发⽣内存泄漏。
(3)电量使⽤情况: 相对于PC来说,移动设备的电池电量是⾮常有限的,保持持久的续航能⼒尤为重要。
另外,android的很多特性都⽐较耗电(如屏幕,GPS,sensor传感器,唤醒机制,CPU,连⽹等的使⽤),我们必须要慎重检查APP的电量使⽤,以免导致⽤户⼿机耗电发热,带来不良体验。
(4)流量使⽤情况: ⽬前的⽹络类型包含2G\3G\4G\wifi,其中还有不同运营商的区分,我们在APP的使⽤中经常遇到⼤资源,重复请求,调⽤响应慢,调⽤失败等各种情况。
在不同的⽹络类型之下,我们不仅要控制流量使⽤,还需要加快请求的响应。
原理以及优化技术要点原理及相关知识介绍请参考google官⽅的教程:具体优化⽅案:代码编写风格细节对性能的影响:1、使⽤优化后的数据容器:请使⽤ Andorid 框架中优化过的数据容器,例如 SparseArray,SparseBooleanArray 和 LongSparseArray。
Android进阶-Android性能优化总结
Android进阶-Android性能优化总结⼀、Android性能优化的⽅⾯针对Android的性能优化,主要有以下⼏个有效的优化⽅法:1.布局优化2.绘制优化3.内存泄漏优化4.响应速度优化5.ListView/RecycleView及Bitmap优化6.线程优化7.其他性能优化的建议下⾯我们具体来介绍关于以上这⼏个⽅⾯优化的具体思路及解决⽅案。
⼆、布局优化关于布局优化的思想很简单,就是尽量减少布局⽂件的层级。
这个道理很浅显,布局中的层级少了,就意味着Android绘制时的⼯作量少了,那么程序的性能⾃然就提⾼了。
如何进⾏布局优化?①删除布局中⽆⽤的控件和层次,其次有选择地使⽤性能⽐较低的ViewGroup。
关于有选择地使⽤性能⽐较低的ViewGroup,这就需要我们开发就实际灵活选择了。
例如:如果布局中既可以使⽤LinearLayout也可以使⽤RelativeLayout,那么就采⽤LinearLayout,这是因为RelativeLayout的功能⽐较复杂,它的布局过程需要花费更多的CPU时间。
FrameLayout和LinearLayout⼀样都是⼀种简单⾼效的ViewGroup,因此可以考虑使⽤它们,但是很多时候单纯通过⼀个LinearLayout或者FrameLayout⽆法实现产品效果,需要通过嵌套的⽅式来完成。
这种情况下还是建议采⽤RelativeLayout,因为ViewGroup的嵌套就相当于增加了布局的层级,同样会降低程序的性能。
②采⽤标签,标签,ViewStub。
标签主要⽤于布局重⽤。
标签⼀般和配合使⽤,可以降低减少布局的层级。
ViewStub提供了按需加载的功能,当需要时才会将ViewStub中的布局加载到内存,提⾼了程序初始化效率。
③避免过度绘制过度绘制(Overdraw)描述的是屏幕上的某个像素在同⼀帧的时间内被绘制了多次。
在多层次重叠的 UI 结构⾥⾯,如果不可见的 UI 也在做绘制的操作,会导致某些像素区域被绘制了多次,同时也会浪费⼤量的 CPU 以及 GPU 资源。
Android开发中的性能优化技巧和最佳实践(八)
Android开发中的性能优化技巧和最佳实践随着移动设备的普及,Android应用开发变得越来越重要。
然而,在开发过程中,我们经常会碰到性能问题。
优化性能是一项重要的任务,它可以提升用户体验,减少应用占用的资源,并延长设备的电池寿命。
本文将介绍一些Android开发中的性能优化技巧和最佳实践,以帮助开发者更好地提升应用的性能。
一、布局优化布局是应用界面的基础,一个糟糕的布局会导致应用界面的卡顿和滚动不流畅。
在进行布局优化时,我们可以遵循以下几点进行操作。
首先,使用与设备屏幕尺寸匹配的布局。
Android支持多种屏幕分辨率和尺寸,为了适应不同的设备,应该尽量避免使用绝对尺寸,而是使用相对尺寸。
可以使用“dp”单位来定义布局中的尺寸,以确保在不同的屏幕上布局都能正确显示。
其次,减少布局层次。
布局层次越多,渲染界面所消耗的资源就越多。
如果可能,应该尽量减少布局层次,合并冗余布局,在代码中进行动态添加和移除视图。
最后,使用ConstraintLayout代替RelativeLayout或LinearLayout。
ConstraintLayout是一个强大的布局管理器,可以根据视图之间的关系自动调整视图的位置和大小。
它可以减少布局嵌套,提高布局效率。
二、图片优化图片是Android应用中常用的资源,优化图片的加载和显示对于提升应用性能非常重要。
以下是几个优化图片的技巧。
首先,选择合适的图片格式。
在Android中,常用的图片格式有JPEG和PNG。
JPEG适用于彩色照片,而PNG适用于图标、按钮等需要保持透明度的图片。
根据图片的具体需求,选择合适的格式可以减少图片的尺寸和加载时间。
其次,压缩图片。
Android提供了多种图片压缩工具,例如TinyPNG、OptiPNG等。
通过压缩图片可以减小图片的文件大小,加快图片加载的速度。
最后,使用适合的图片尺寸。
不同分辨率的设备可能需要不同尺寸的图片进行适配,使用合适的尺寸可以避免图片的缩放,减少内存的占用和加载时间。
Android设备的图形资源优化技术
Android设备的图形资源优化技术一、引言随着智能手机和平板电脑的普及,Android设备已经成为人们日常生活中不可或缺的工具。
在开发Android应用程序时,图形资源的优化是一个至关重要的任务。
本文将重点讨论Android设备中图形资源的优化技术,以帮助开发者提升应用程序的性能和用户体验。
二、图形资源的类型和特点在Android应用开发中,常见的图形资源包括图片、图标、矢量图形等。
这些图形资源对应用程序的体积和性能有着直接的影响。
首先,图形资源的体积越大,应用程序安装包的大小也会相应增大,增加用户下载和安装的时间。
其次,图形资源的加载和显示过程会占用系统资源和内存,导致应用程序运行缓慢甚至崩溃。
三、图形资源的格式选择为了减小图形资源的体积,Android开发者可以选择合适的图形格式。
常见的图形格式包括JPEG、PNG、GIF和WebP等。
每种格式都有自己的特点和适用场景。
例如,JPEG格式适合存储照片等颜色丰富、细节丰富的图像,但不支持透明度。
PNG格式则适合存储颜色较少、需要透明度的图标和简单的图形,但文件较大。
GIF格式常用于存储动画效果,但只支持256色。
WebP格式是Google推出的一种新型图形格式,具有较好的压缩率和透明度支持。
四、图形资源的压缩和优化为了减小图形资源的体积,开发者可以采用图形资源的压缩和优化技术。
首先,可以使用图片编辑工具对图形资源进行压缩,减小图像的尺寸和色彩深度。
其次,可以采用无损压缩算法,如PNGCrush和PNGOUT,减小图像文件的体积而不影响图像质量。
还可以通过减少图片的颜色数和使用有损压缩算法,如JPEG压缩,来进一步减小图像文件的大小。
此外,可以将图形资源转换为WebP格式,以获得更好的压缩效果。
五、图形资源的适配和缩放在不同的Android设备上,屏幕的尺寸和分辨率各不相同。
为了在不同的设备上呈现良好的图像效果,开发者需要对图形资源进行适配和缩放。
移动端开发技巧:优化页面加载速度(三)
移动端开发技巧:优化页面加载速度在移动互联网时代,用户对页面加载速度的要求越来越高。
一个快速加载的页面不仅能提升用户体验,还可以降低用户的流失率。
因此,优化页面加载速度成为了移动端开发中的一个重要环节。
本文将从几个方面介绍一些优化页面加载速度的技巧。
一、图片优化图片是页面加载速度的主要因素之一。
移动设备的带宽相对有限,因此需要对图片进行优化。
首先,选择合适的图片格式。
JPEG格式适用于彩色照片和复杂图像,而PNG格式适合简单的图标和线条图像。
选择适当的图片格式可以减小图片文件大小,从而加快加载速度。
其次,进行图片压缩。
可以使用专业的图片处理软件来进行压缩,也可以使用在线的图片压缩工具。
通过压缩图片,可以减小它们的文件大小,从而减少加载时间。
另外,延迟加载也是一种优化图片加载速度的方法。
可以使用JavaScript插件来实现延迟加载。
当用户滚动到需要加载的图片时,再进行加载。
这样可以减少初始加载的数据量,加快页面的加载速度。
二、合并和压缩代码在移动端开发中,页面的代码量相对较大。
为了减小页面的大小,可以将多个CSS文件合并成一个,将多个JavaScript文件合并成一个。
合并文件可以减少HTTP请求的次数,从而加快页面的加载速度。
如果有多个CSS文件或JavaScript文件需要加载,浏览器需要发起多个HTTP请求,而合并后只需要一次请求。
此外,对代码进行压缩也是一种减小文件大小的方式。
可以使用工具如CSSMin、UglifyJS等来对代码进行压缩。
压缩后的文件不但大小更小,加载速度也更快。
三、使用缓存在移动端开发中,使用缓存技术也是一种优化页面加载速度的常用方法。
在服务器端,可以使用HTTP的缓存机制来缓存页面的静态资源。
通过设置合适的HTTP响应头,可以告诉浏览器将这些资源缓存在本地,下次访问时直接从缓存中读取,而不需要再次请求。
这样可以减少网络请求的次数,提升页面的加载速度。
在客户端,可以使用LocalStorage或SessionStorage来缓存数据。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Android 图片加载性能优化总结一、Android Bitmap加载大尺寸图片优化:压缩原因:1.imageview大小如果是200*300那么加载个2000*3000的图片到内存中显然是浪费可耻滴行为;2.最重要的是图片过大时直接加载原图会造成OOM异常(out of memory内存溢出)所以一般对于大图我们需要进行下压缩处理看不懂英文的话木有关系,本篇会有介绍主要处理思路是:1.获取图片的像素宽高(不加载图片至内存中,所以不会占用资源)2.计算需要压缩的比例3.按将图片用计算出的比例压缩,并加载至内存中使用官网大图片加载教程(上面网址里的)对应代码就是:/*** 获取压缩后的图片* @param res* @param resId* @param reqWidth 所需图片压缩尺寸最小宽度* @param reqHeight 所需图片压缩尺寸最小高度* @return*/public static Bitmap decodeSampledBitmapFromResource(Resourcesres, int resId, int reqWidth, int reqHeight) {// 首先不加载图片,仅获取图片尺寸final BitmapFactory.Options options= new BitmapFactory.Options();// 当inJustDecodeBounds设为true时,不会加载图片仅获取图片尺寸信息options.inJustDecodeBounds = true;// 此时仅会将图片信息会保存至options对象内,decode方法不会返回bitmap 对象BitmapFactory.decodeResource(res, resId, options);// 计算压缩比例,如inSampleSize=4时,图片会压缩成原图的1/4options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);// 当inJustDecodeBounds设为false时,BitmapFactory.decode...就会返回图片对象了options.inJustDecodeBounds = false;// 利用计算的比例值获取压缩后的图片对象return BitmapFactory.decodeResource(res, resId, options);}代码详解:核心方法是BitmapFactory.decode...(...., options)...的意思是此外还有一系列的decodeFile/decodeStream等等方法,都是利用options灵活解析获取图片,只不过解析图片的来源不同罢了,比如网络图片获取,一般就是解析字节流信息然后decode获取图片实例Options是图片配置信息,参数详细介绍下:inJustDecodeBounds 是否只解析边界设为true时去decode获取图片,只会加载像素宽高信息设为false时decode则会完全加载图片inSampleSize 压缩比例比如原图200*300,如果值是2时会压缩成100*150; 是4则图片压缩成50*75最好是2的幂数,比如2 4 8 16 .....outHeight 图片原高度outWidth 图片原宽度其他参数自行研究,这里暂时只用到这几个decodeSampledBitmapFromResource方法内的三段代码对应上面的三步流程难点在于中间那步,压缩比例的计算,官网同样提供了个calculateInSampleSize方法其中reqWidth和reqHeight是所需图片限定最小宽高值/*** 计算压缩比例值* @param options 解析图片的配置信息* @param reqWidth 所需图片压缩尺寸最小宽度* @param reqHeight 所需图片压缩尺寸最小高度* @return*/public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {// 保存图片原宽高值final int height = options.outHeight;final int width = options.outWidth;// 初始化压缩比例为1int inSampleSize = 1;// 当图片宽高值任何一个大于所需压缩图片宽高值时,进入循环计算系统if (height > reqHeight || width > reqWidth) {final int halfHeight = height / 2;final int halfWidth = width / 2;// 压缩比例值每次循环两倍增加,// 直到原图宽高值的一半除以压缩值后都~大于所需宽高值为止while ((halfHeight / inSampleSize) >= reqHeight&& (halfWidth / inSampleSize) >= reqWidth) {inSampleSize *= 2;}}return inSampleSize;}利用此方法获取到所需压缩比例值,最终获取到压缩后的图片~以上代码能够看懂的话,下面这段/*扯淡*/可以跳过逻辑是将原图宽高一半一半的缩减,一直减到宽高都小于自己设定的限定宽高时为止,测试的时候问题来了原图400*300,我限定值200*150,if满足进入,while循环第一次,400/2/1=200不满足>的条件~结束循环,最终返回了个inSampleSize=1给我马丹我限定值正好是原图的一半啊,你应该返回给我2啊~你特么最后返回个1给我,那压缩处理后的图还是400*300!!!当我将限定值稍微改一下变成195*145稍微降低一点点时~if满足进入,while循环第一次,400/2/1>195满足~然后压缩比例1*2变成了2,在下一次while循环时不满足条件结束,最后返回比例值2~ 满足压缩预期官网的这个方法是: 将图片一半一半的压缩,直到压缩成成大于所需宽高数的那个最低值大于~不是大于等于,所以就会出现我上面那种情况,我觉得方法不是太好= = 能满足压缩的需求,但是压缩的比例不够准确~所以最好改成大于等于,如下(个人意见,仅供参考,在实际压缩中很少遇到恰巧等于的这个情况,所以>和>=差别也不大额~看我这扯扯淡就当对计算比例的逻辑加深个理解吧)while ((halfHeight / inSampleSize) >= reqHeight&& (halfWidth / inSampleSize) >= reqWidth) {inSampleSize *= 2;}优化:还是上面例子,如果限定了200*150,而原图是390*290会是个啥情况?还是第一次while循环,390/2/1结果是195不满足>200的情况,结束循环,比例值为1,最后图片压缩成400*300虽然压缩一次以后没有满足大于所需宽高,但是和所需宽高很接近啊!!!能不能做一个获取压缩成最接近所需宽高数的比例值呢?我也不知道= = 回头可以慢慢研究, 这个"接近"的定义比较模糊,不好掌握~找了几个有名的图片加载开源框架发现也都没有这种处理- -不知道是这样设计是不需要呢,还是没啥用呢以上,图片的像素大小已经做了缩放,但是图片的大小除了和像素有关,还和色彩样式有关不同的样式决定了图片单个像素占的字节数比如,图片默认的色彩样式为ARGB_8888,每个像素占4byte(字节)大小可以看到一共有四种色彩样式ALPHA_8 每个像素只要1字节~可惜只能代表透明度,没有颜色属性ARGB_4444 每个像素要2字节~带透明度的颜色~可惜官方不推荐使用了ARGB_8888 每个像素要4字节~带透明度的颜色, 默认色样RGB_565 每个像素要2字节~不带透明度的颜色默认为ARGB_8888,如果想丧心病狂的继续减少图片所占大小~不需要透明度参数的话,那就可以把色彩样式设为RGB_565设置方法是在BitmapFactory.decode..获取图片事例时修改配置参数的inPreferredConfig 参数opts.inPreferredConfig = Bitmap.Config. RGB_565 ;想亲自撸一撸试一试压缩图片了吧?要注意点问题,如果用res包下图片测试的话,你会发现有图片尺寸有点混乱那是因为在drawable-*dpi文件夹中的图片会根据对应对应的屏幕密度值不同自动进行一定的缩放,比如放在drawable-hdpi里的图片,直接不经过压缩BitmapFactor.decode..出来,会发现bitmap的宽高值是原图的2/3,测试的时候图片记得放在drawable包下(没有的话自己res下新建一个),否则你会被奇怪的宽高值弄凌乱的,具体变化原因参考源代码处理,或者网上搜搜看。
还有就是BitmapFactory.decodeStream方法会偶尔解析图片失败(好像是安卓低版本的一个bug),此时推荐做法是将流转换为字节流处理,然后利用decodeByteArray方法获取图片。
二、Android 加载多张图片的缓存处理一般少量图片是很少出现OOM异常的,除非单张图片过~大~ 那么就可以用教程一里面的方法了通常应用场景是listview列表加载多张图片,为了提高效率一般要缓存一部分图片,这样方便再次查看时能快速显示~不用重新下载图片但是手机内存是很有限的~当缓存的图片越来越多,即使单张图片不是很大,不过数量太多时仍然会出现OOM的情况了~本篇则是讨论多张图片的处理问题图片缓存的一般处理是1.建立一个图片缓存池,用于存放图片对应的bitmap对象2.在显示的时候,比如listview对应适配器的getView方法里进行加载图片的工作, 先从缓存池通过url的key值取,如果取到图片了直接显示,如果获取不到再建立异步线程去下载图片(下载好后同时保存至图片缓存池并显示)但是缓存池不能无限大啊~不然就会异常了,所以通常我们要对缓存池进行一定控制需要有两个特性:总大小有个限制,不然里面存放无限多的图片时会内存溢出OOM异常当大小达到上限后,再添加图片时,需要线程池能够智能化的回收移除池内一部分图片,这样才能保证新图片的显示保存异步线程下载图片神马的简单,网上异步下载任务的代码一大堆,下载以后流数据直接decode成bitmap图片即可难点在与这个图片缓存池的设计,现在网上的实现主要有两种1.软引用/弱引用2.LruCache-----------------------------------------------------------------------拓展: java中4种引用分类强引用平常使用的基本都是强引用,除非主动释放(图片的回收,或者==null赋值为空等),否则会一直保存对象到内存溢出为止~软引用 SoftReference在系统内存不够时,会自动释放部分软引用所指对象~弱引用 WeakReference系统偶尔回收扫描时发现弱引用则释放对象,即和内存够不够的情况无关,完全看心情~虚引用不用了解,其实我也不熟悉框架基本都比较爱用这个软应用保存图片作为缓存池,这样在图片过多不足时,就会自动回收部分图片,防止OOM但是有缺点,无法控制内存不足时会回收哪些图片,如果我只想回收一些不常用的,不要回收常用的图片呢?于是引入了二级缓存的逻辑即设置两个缓存池,一个强引用,一个软引用, 强引用保存常用图片,软应用保存其他图片~强引用因为不会自动释放对象,所以大小要进行一定限定,否则图片过多会异常, 比如控制里面只存放10张图片,然后每次往里面添加图片的时候,检查如果数量超过10张这个阀值,临界点值时,就移除强引用里面最不常用的那个图片,并将其保存至软应用缓存池中~整个缓存既作为一个整体(一级二级缓存都是内存缓存~每次显示图片前都要检查整个缓存池中有没有图片)又有一定的区分(只回收二级缓存软引用中图片,不回收一级缓存中强引用的图片~)代码实现软应用缓存池类型作为二级缓存:HashMap<String,SoftReference<Bitmap>> mSecondLevelCache = new HashMap<String, SoftReference<Bitmap>>();强引用作为一级缓存,为了实现删除最不常用对象,可以用LinkedHashMap<String,Bitmap> 类LinkedHashMap对象可以复写一个removeEldestEntry,这个方法就是用来处理删除最不常用对象逻辑的按照之前的设计就可以这么写:final int MAX_CAPACITY = 10; // 一级缓存阈值// 第一个参数是初始化大小// 第二个参数0.75是加载因子为经验值// 第三个参数true则表示按照最近访问量的高低排序,false则表示按照插入顺序排序HashMap<String, Bitmap> mFirstLevelCache = new LinkedHashMap<String, Bitmap>( MAX_CAPACITY / 2, 0.75f, true) {// eldest 最老的对象,即移除的最不常用图片对象// 返回值true即移除该对象,false则是不移除protected boolean removeEldestEntry(Entry<String, Bitmap> eldest) {if (size() > MAX_CAPACITY) {// 当缓存池总大小超过阈值的时候,将老的值从一级缓存搬到二级缓存mSecondLevelCache.put(eldest.getKey(),new SoftReference<Bitmap>(eldest.getValue()));return true;}return false;}};每次图片显示时即使用时,如果存在与缓存中,则先将对象从缓存中删除,然后重新添加到一级缓存中的最前端会有三种情况1.如果图片是从一级缓存中取出来的,则相当于把对象移到了一级缓存池的最前端(相当于最近使用的一张图片)~2.如果图片是从二级缓存中取出来的,则会存到一级缓存池最前端并检测,如果超过阀值,则将最不常用的一个对象移动到二级缓存中3.如果缓存中没有,那就网上下载图片,下载好以后保存至一级缓存中,同样再进行检测是否要移除一个对象至二级缓存中结合现实例子理解下(如果以上逻辑了解可以跳过):美国篮球,比如有一个最高水平的联赛NBA,还有一个次一级的联赛NBDL~一级联赛NBA的排名按最近一次拿冠军的时间由近到远排列,我们规定,每一季度比赛都要产生一个冠军,冠军可能是已有的任何一个队伍也可能是一个民间来的新队伍~而当一个队伍获取冠军的时候就给他加到一级队伍NBA里~ 由于是最近一次拿冠军,所以加进去的时候也是排名第一NBA作为最高水平,我们对数量是有限制的,所以每次有新冠军产生的时候我们都做一次检测,如果队伍总数量超过20支,那么就移除排名最低即离上次获冠军时间最长的那个最差队伍.如果每季度比赛拿冠军相当于一次图片使用操作,那上面三种情况就对应我们例子中的: 1.NBA的队伍拿冠军,相当于这个队伍排名变成了第一名~但NBA队伍总数不变,没有新加入来的2.NBDL二级联赛拿冠军,则加入到NBA里面,且变成了第一名~由于NBA队伍相当于增加了一个,那就要检测一下是否超过20支并将最差成绩的挤到NBDL中3.民间来大神了虐了全部的队伍拿了冠军,那直接加入NBA然后变成第一名,同样,检测NBA 球队数量判断是否要挤出去一队NBDL球队相当于软应用的二级缓存池, 不限定数量~ 多少都可以, 直到美国篮联维护全部NBA NBDL球队的资金不够了(相当于图片过多应用内存不足了)则自动解散一部分球队,落入民间,直到下一次获取总冠军再加入进来(相当于图片从缓存中移除了,下次使用要重新下载)~那NBA就相当于一级缓存,经常拿冠军(相当于高频率使用的图片),那我们就不想因为资金不足随机解散几个球队恰好就解散了NBA队伍,则规定资金不够时只解散二级联赛NBDL的队伍~因为他们获取比赛几率低一点~民间队伍存在与联赛系统之外(相当于不存在缓存中的图片), 而任何一个NBA NBDL联赛球队我们都可以理解为都是民间晋级过来的~只不过从民间获取总冠军并加入联赛需要一个取名字啊登记啊等等的办手续过程(下载图片),比较麻烦,所以我们要尽可能的少办手续~而联赛队伍(包括NBA NBDL)获取总冠军则不需要麻烦的手续,可以直接参加比赛去拿冠军(直接获取显示)两个联赛,一个常用的限定数量,一个不常用的不限定数量,但是资金不足时自动回收部分二级球队~相当于图片的二级缓存Disk缓存可以简单的理解为将图片缓存到sd卡中~由于内存缓存在程序关闭第二次进入时就清空了,对于一个十分常用的图片比如头像一类的~我们希望不要每次进入应用都重新下载一遍,那就要用到disk缓存了,直接图片存到了本地,打开应用时直接获取显示~网上获取图片的大部分逻辑顺序是内存缓存中获取显示(强引用缓存池->弱引用缓存池) -> 内存中找不到时从sd卡缓存中获取显示-> 缓存中都没有再建立异步线程下载图片,下载完成后保存至缓存中按照获取图片获取效率的速度,由快到慢的依次尝试几个方法以文件的形式缓存到SD卡中,优点是SD卡容量较大,所以可以缓存很多图片,且多次打开应用都可以使用缓存,缺点是文件读写操作会耗费一点时间,虽然速度没有从内存缓存中获取速度快,但是肯定比重新下载一张图片的速度快~而且还不用每次都下载图片浪费流量~所以使用优先级就介于内存缓存和下载图片之间了注意:sd卡缓存一般要提前进行一下是否装载sd卡的检测, 还要检测sd卡剩余容量是否够用的情况程序里也要添加注明相应的权限使用LruCache处理图片缓存以上基本完全掌握了,每一张图最好再进行一下教程(一)里面介绍的单张缩放处理,那基本整个图片缓存技术就差不多了但随着android sdk的更新,新版本其实提供了更好的解决方案,下面介绍一下摘取段对软引用的介绍Avoid Soft References for CachingIn practice, soft references are inefficient for caching. The runtime doesn't have enough information on which references to clear and which to keep. Most fatally, it doesn't know what to do when given the choice between clearing a soft reference and growing the heap. The lack of information on the value to your application of each reference limits the usefulness of soft references. References that are cleared too early cause unnecessary work; those that are cleared too late waste memory.Most applications should use an android.util.LruCache instead of soft references. LruCache has an effective eviction policy and lets the user tune how much memory is allotted.简单翻译一下我们要避免用软引用去处理缓存在实践中,软引用在缓存的处理上是没有效率的。