在没有遇到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;
}
}