APP下载

浅析在Android应用开发中对图片加载的优化分析

2021-11-07胡畅霞陈娜刘晓星

电脑知识与技术 2021年25期

胡畅霞 陈娜 刘晓星

摘要:图片作为Android应用中重要的资源信息,保证图片资源的流畅显示对用户人机交互体验的提升至关重要。该文作者以在ListView控件中加载图片资源为例,首先简述以传统加载图片的方式,随后给出两种优化方案:1)Adapter优化;2)引用Android Image Loader 框架。通过优化达到流畅加载图片资源的效果,增强用户体验。

关键词:图片加载优化;Adapter优化; Android Image Loader框架

中圖分类号:TP311      文献标识码:A

文章编号:1009-3044(2021)25-0078-02

1引言

图片资源作为Android应用中不可或缺的资源,丰富着信息内容,使用户更加容易理解界面传达的信息。在实际开发中,因为程序需要经常连接网络,且界面上存在着丰富的图片资源,所以加载图片时系统资源的消耗是巨大的。ListView控件作为Android中最常见的控件,因此需要加载网络上的图片资源时就经常需要用到ListView控件。为了使人机交互友好,就要保证图片加载要得到快速的响应,尽量避免加载超时或者延时等现象。本文作者以在ListView控件中加载网络图片资源为例,浅析在Android开发中对图片优化的如下几种方法。

2传统方式加载图片资源

利用传统方式在ListView中加载图片资源,首先创建URL对象传入网络图片的网址,网址必须是绝对路径,得到图片的数据流。在Android中,提供了BitmapFactory类,用于从不同的数据源来解析、创建Bitmap对象。Bitmap对象在如TextView 控件中显示,最后关闭数据流。

示例代码:

Bitmap bitmap = null;

URL url;

try {

url = new URL(“视频网址”);

InputStreamiliu = url.openStream();

bitmap = BitmapFactory.decodeStream(iliu);

iliu.close();}

catch (Exception e) {e.printStackTrace();}

传统方式简单、直接、书写简单,但在UI主线程中执行联网耗时操作,不但导致图片资源加载速度慢,而且影响其他项的响应速度。

3利用Adapter优化的方式,加载图片资源

在使用ListView 控件加载图片资源时,Android引入Adapter机制作为复杂数据的展示和转化的载体,Adapter作为ListView控件与数据源之间的“中介”,当每条数据进入到可见区时,Android会调用Adapter中的getView()方法来返回代表着具体数据的视图,由于数据成千上万,所以getView()方法被多次调用,因此通过减少getView()方法的调用次数来优化Adapter会提高加载图片资源的加载速度。

3.1 利用ViewHolder模式优化Adapter

ViewHolder类是Android定义的一个静态类,并不是在Android API中提供的方法。ViewHolder模式的存在,可以大大降低多余的findViewById()方法的调用,而是把使用控件的代码放在ViewHolder类里面,然后把View.setTag(holder)放在view中,这样再次使用时就可以直接调用。

利用ViewHolder模式优化Adapter,重复利用convertView回收视图,减少getView()的调用次数达到优化的效果。这种模式加载图片资源的操作还是在UI主线程中执行,在图片资源数目少时,这种方法会有一定的效果,但是图片资源量大时,依旧会阻塞UI主线程,导致程序的响应慢等现象,治标不治本。

3.2 利用工作线程加载数据

由于加载网络图片资源,既涉及联网操作,又包含着大量的数据信息,因此我们需要为此操作重新开辟一个新的线程来减轻UI主线程的负担。本文作者在Adapter中使用到的是轻量级AsyncTask工作线程处理方式:当程序需要启动后台线程来加载图片资源时,使用该工作线程可以很容易做到,同时在UI线程中也能得到自动返回过来的结果。需要注意的是,使用AsyncTask时有如下几点事项需要考虑:

1)创建AsyncTask实例的位置:须在主线程中;

2)调用AsyncTask的execute()方法的位置:须在主线程中;

3)AsyncTask类中的方法,如onPreExecute、onPostExecute、doInBackground和onProgressUpdate等,它们是由Android系统亲自调用,程序员是不能写代码去调用的;

4)AsyncTask不能被多次调用,否则会抛出异常,所以只能被执行一次。

主要代码如下:

class MyPictTaskextends AsyncTask {

WeakReferenceimgViewRef;

intshuliang = 0; public BitmapWorkerTask(ImageViewmyimageView) {

imgViewRef= new WeakReference(myimageView);     }

protected Bitmap doInBackground(Integer...params) {