listview优化问题

来源:互联网 发布:农村淘宝合伙人网站 编辑:程序博客网 时间:2024/06/03 15:15

Listview优化问题

一、   优化背景

后视镜项目中,需要设计一个视频回放的apk,spec定义如下。产品定义需求如下:

回放:点击文件名用设备自带播放器播放。

录像文件名:文件锁开关图标+存储时间+文件名组成。

录像文件锁:默认文件锁为打开状态(文件可被覆盖),如点击文件锁即文件锁图标变为锁止状态(文件无法被覆盖),再次点击文件锁图标为打开状态。

视频及照片文件删除或同步:长按文件2秒钟,弹出:“删除”、“同步至手机”按钮。

 

二、           设计方案

1         需求分析

根据需求,可以划分为以下几个部分:视频和图片分开加载显示,录像加锁功能,文件删除多选打开等文件操作。

2         设计方案

2.1        文件加载方式

通过ContentPrivider扫描sd卡所有图片和视频,在扫描前先将sd卡整个扫描一遍,不然的话可能刚刚添加的图片是不会查找出来的。

public void allScan(){

       sendBroadcast(newIntent(Intent.ACTION_MEDIA_MOUNTED,Uri.parse("file://"

       +Environment.getExternalStorageDirectory())));

}

 

uri =MediaStore.Video.Media.EXTERNAL_CONTENT_URI; 

uri =MediaStore.Images.Media.EXTERNAL_CONTENT_URI; 

          mCursor = contentResolver.query(uri, null, where, null,

                            null);

 

2.2        Listview显示

在实际优化中,有两种优化方式。

l  初始是采用直接继承BaseAdapter基类,public FileAdapter(ListView

mlistview,Context context,List<String> p),参数传进来是list<String>p,也就是说,在扫描出cursor之后,还需要将cursor的data属性传到list集合中,而adapter再对传进来的p进行处理。

进行优化处理——将cursor解析封装成一个一个对象集合,

public class RecordInfo {

      privateString _dispalyName;

      privateLong _size;

      privateString _data;

      privateString _tags;

      privatelong _id;

       privateboolean _checked;}

分装的好处是,由于在adapter进行操作数据集的时候,如果单独传进来的是一个路径,那么还需要将路径不断转化来转化去,系统性能较差。采用cursor先封装的好处是,有些数据已经有的东西,就可以直接拿出来用了,减少耗时操作,提高系统性能。

l  第二种方案是继承CursorAdapter。先来介绍下cursoradapter:

CursorAdapter是继承了BaseAdapter后覆盖它的getView方法,在该方法中调用了newView和bindView方法,我们在写CursorAdapter时必须实现它的这两个方法。

1)       newView:并不是每次都会被调用的,它只在实例化的时候被调用,数据增加时也会调用,但是在重绘(比如修改条目中的TextView的内容)的时候不会被调用。

2)       bindView:在绘制Item之前一定会调用bindView方法,它在重绘的时候也同样会被调用。

3)       changeCursor:调用此方法后会把mCursor置为新传过来的cursor,把原来的cursor返回去并关掉。它的方法类似于adapter.notifyDataSetChanged()方法。

对比BaseAdapterCursorAdapter

CursorAdapter是继承于BaseAdapter的,是对BaseAdapter的进一步扩展。CursorAdapter适用于Cursor类型的数据集(从数据库读取的数据一般是这类型),而BaseAdapter是哪种类型的数据集都是适用的,包括Cursor,只不过对于Cursor,使用CursorAdapter比使用BaseAdapter要方便得多,因为很多的工作CursorAdapter都帮你做了。CursorAdapter还可以监听到数据的变化,实时更新数据。

1. 

 

2.3        缩略图加载+异步操作+Loader

Android的加载器(loader)是从Android3.0开始出来的东西。要理解这里首先要先理解为什么会出现加载器呢?

如果没有加载器。。。。

首先Activity是我们的前端页面展现,数据库是我们的持久化地址,那么正常的逻辑就是在展示页面的渲染页面的阶段进行数据库查询。拿到数据以后才展示页面。但是这个逻辑有一些缺点:

首先是查询数据的逻辑放在了UI生成的同个线程中,这个就意味着在查询数据的时候,UI页面生成的工作被阻塞住了。UI一旦被阻塞用户就会被感知出来了,因此就会出现各种无相应页面(Application Not Response),或者activity页面延迟的现象,这对用户体验来说是不可接受的。

其次是在渲染页面的时候需要固定进行一次数据查询,但是这个是很不节省资源的。加入一个activity从一个停止状态回到前台,那么这个时候尽管数据并没有变化,但是也需要进行一次query操作。在浪费资源的同时也增加了页面渲染失败的风险。

还有就是当数据变化的时候如何通知页面进行修改呢?这个时候往往就要创建一个monitor角色,来当数据源变化的时候来让页面重新调用requery。

Loader做了两件时:1 在单独的线程中读取了数据;2 监视数据的更新。

2.4        Checkbox+listview

原先的baseadapter对checkbox的操作是创建一个集合存储这些checkbox的状态,但是在cursoradapter操作过程有些问题。Cursoradapter对于数据监听进行更新adapter,新加进来的数据的checkbox状态没有设置,所以会出现问题。对此的解决方案是,一检测到数据变动就直接进行赋值,但是这种方案不可行,如果数据是增加的,那么是可以接受的,但是如果是删除了数据变动,那么就麻烦了。我的修改方式是,在bindView里面检测是否有这个id的存在,没有就复制。

采用封装recordInfo的那种方式对checkbox的处理是,给recordInfo一个标志位,一开始全部赋予false,checkbox选中赋予true。删除只需要遍历为true的对象进行删除。

2.5        删除记录

class DeleteFileThread extends Thread {

       public Handler mHandler;

       private ArrayList<Long> mSrcFiles =null;

       private int event = EVENT_DELETE_FILE_OK;

       public void run() {               

              for (int i = 0; i <mSrcFiles.size(); i++) {

                     int result = getContentResolver().delete(uri,"_id=" + mSrcFiles.get(i), null);

                     if(result == 0)

                            event = EVENT_FAILED;

                  }

              // Send response message to UI thread

              Message msg = handler.obtainMessage();

              Bundle b = new Bundle();           

              b.putInt("event", event);

              msg.setData(b);

              handler.sendMessage(msg);

       }

      

       public DeleteFileThread(ArrayList<Long>srcFiles) {          

                  mSrcFiles= srcFiles;                

           }

    }

   采用cursoradapter的方式删除会自动更新数据库,采用recordInfo方式,注意要在recordInfos也要删除对象,不然会持有该对象无法更新listview。

0 0
原创粉丝点击