Android学习笔记--初见AsyncQueryHandler

在没有遇到AsyncQueryHandler之前

new Thread(new Runnable() {
            @Override
            public void run() {
            .......
                Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                ContentResolver mContentResolver =
                        getContentResolver();

                Cursor mCursor = mContentResolver.query(mImageUri, null,
                        MediaStore.Images.Media.MIME_TYPE + "=? or "
                                + MediaStore.Images.Media.MIME_TYPE + "=? or "
                                + MediaStore.Images.Media.MIME_TYPE + "=?",
                        new String[]{"image/jpeg", "image/png",
                                "image/x-ms-bmp"},
                        MediaStore.Images.Media.DATE_MODIFIED);
                        ......
            }
    }

因为通过ContentProvider查询是耗时操作,通常需要要开启一个子线程来进行操作。而AsyncQueryHandler就是解决我们需要开启新的一个线程的问题,从名字可以看出它属于异步操作。

如果用AsyncQueryHandler,我们可以

  AsyncQueryHandler ash = new AsyncQueryHandler(getActivity().getContentResolver()) {
           //查询完成的回调
            @Override
            protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
                super.onQueryComplete(token, cookie, cursor);
//                Utils.printCursor(cursor);
                VideoListAdapter videoListAdapter = new VideoListAdapter(getActivity(), cursor);
                mMediaLv.setAdapter(videoListAdapter);
            }
        };
        String orderBy = MediaStore.Video.Media.TITLE + " ASC";
        String[] selectionArgs = null;
        Object cookie = null;
        int token = 0;
        Uri uri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
        String[] projection = {MediaStore.Video.Media._ID, MediaStore.Video.Media.TITLE
                , MediaStore.Video.Media.SIZE, MediaStore.Video.Media.DATA, MediaStore.Video.Media.DURATION};
        String selection = null;
        ash.startQuery(token, cookie, uri, projection, selection, selectionArgs, orderBy);

以上操作都是在主线程中完成,不需要我们新开一个线程。查询完的结果通过onQueryComplete接口回调,其中Cursor是返回到查询的数据。
上面代码中VideoListAdapter是继承自CursorAdapter,代码如下。

public class VideoListAdapter extends CursorAdapter {

    public VideoListAdapter(Context context, Cursor c) {
        super(context, c);
    }

    //创建一个View
    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        View view = View.inflate(context, R.layout.adapter_video_list, null);
        ViewHolder viewHolder=new ViewHolder(view);
        view.setTag(viewHolder);
        return view;
    }

    //绑定数据到View
    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        ViewHolder holder= (ViewHolder) view.getTag();

        VideoItem videoItem=VideoItem.fromCursor(cursor);

        holder.mTvTitle.setText(videoItem.getTitle());
        holder.mTvSize.setText(Formatter.formatFileSize(context,videoItem.getSize()));
        holder.mTvDuration.setText(Utils.formatterMills(videoItem.getDuration()));
    }


    static class ViewHolder {
        @BindView(R.id.tv_title)
        TextView mTvTitle;
        @BindView(R.id.tv_size)
        TextView mTvSize;
        @BindView(R.id.tv_duration)
        TextView mTvDuration;

        ViewHolder(View view) {
            ButterKnife.bind(this, view);
        }
    }
}

注意如果要使用CursorAdapter ,那么在查询的时候必须包括_id那一列,官方文档有如下一句话:

The Cursor must include a column named "_id" or this class will not work.
 Additionally, using {@link android.database.MergeCursor} with this class will not work if the merged Cursors have overlapping values in their "_id"
  columns.

其中VideoItem的代码为:

public class VideoItem implements Serializable{
    //Video名字
    String title;

    //Video时长
    Long duration;

    //Video大小
    Long size;

    //Video路径
    String data;

    public  static  VideoItem fromCursor(Cursor cursor){
        VideoItem videoItem=new VideoItem();
        videoItem.setData(cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.DATA)));
        videoItem.setTitle(cursor.getString(cursor.getColumnIndex(MediaStore.Video.Media.TITLE)));
        videoItem.setDuration(cursor.getLong(cursor.getColumnIndex(MediaStore.Video.Media.DURATION)));
        videoItem.setSize(cursor.getLong(cursor.getColumnIndex(MediaStore.Video.Media.SIZE)));
        return  videoItem;
    }
    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Long getDuration() {
        return duration;
    }

    public void setDuration(Long duration) {
        this.duration = duration;
    }

    public Long getSize() {
        return size;
    }

    public void setSize(Long size) {
        this.size = size;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值