我正在使用 BaseAdapter 列出设备内存中的视频,我注意到滚动效果不是很好,非常慢。 我应该使用不同的方法来完成这项工作,还是有办法改进这项工作?
public class StoredVideo extends Activity {
public final static String EXTRA_MESSAGE = "it.mypackage.com";
private Cursor videocursor;
private int video_column_index;
ListView videolist;
int count;
String[] thumbColumns = { MediaStore.Video.Thumbnails.DATA,
MediaStore.Video.Thumbnails.VIDEO_ID };
private String thumbPath;
SharedPreferences pref;
String account;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.videomain);
pref = getSharedPreferences("AppPref", MODE_PRIVATE);
init_phone_video_grid();
}
@SuppressWarnings("deprecation")
private void init_phone_video_grid() {
System.gc();
String[] proj = { MediaStore.Video.Media._ID,
MediaStore.Video.Media.DATA,
MediaStore.Video.Media.DISPLAY_NAME,
MediaStore.Video.Media.SIZE };
String orderBy = android.provider.MediaStore.Video.Media.DATE_TAKEN;
videocursor = managedQuery(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
proj, null, null, orderBy + " DESC");
count = videocursor.getCount();
videolist = (ListView) findViewById(R.id.PhoneVideoList);
videolist.setAdapter(new VideoAdapter(getApplicationContext()));
videolist.setOnItemClickListener(videogridlistener);
videolist.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> av, View v, int pos, long id) {
return onLongListItemClick(v, pos, id);
}
protected boolean onLongListItemClick(View v, final int pos, long id) {
final String str= videolist.getItemAtPosition(pos).toString();
Log.i("ListView", "onLongListItemClick stirng=" + str);
AlertDialog.Builder builder = new
AlertDialog.Builder(StoredVideo.this);
builder.setMessage("Are you sure you want to delete this video ?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if(videocursor.moveToFirst()) {
videocursor.moveToPosition(pos);
video_column_index = videocursor
.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
String filename = videocursor.getString(video_column_index);
removeMedia(filename);
videocursor.close();
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
init_phone_video_grid();
}
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
return true;
}
});
}
private OnItemClickListener videogridlistener = new OnItemClickListener() {
public void onItemClick(AdapterView parent, View v, int position,
long id) {
System.gc();
video_column_index = videocursor
.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
videocursor.moveToPosition(position);
String filename = videocursor.getString(video_column_index);
Log.d("TAGME", filename);
String videoinfo[] = new String[2];
int videoId = videocursor.getInt(videocursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID));
Cursor videoThumbnailCursor = managedQuery(MediaStore.Video.Thumbnails.EXTERNAL_CONTENT_URI,
thumbColumns, MediaStore.Video.Thumbnails.VIDEO_ID+ "=" + videoId, null, null);
if (videoThumbnailCursor.moveToFirst()) {
thumbPath = videoThumbnailCursor.getString(videoThumbnailCursor.getColumnIndex(MediaStore.Video.Thumbnails.DATA));
Log.d("ThumbPath: ",thumbPath);
}
videoinfo[0] = filename;
videoinfo[1] = thumbPath;
Intent intent = new Intent(StoredVideo.this, ViewVideo.class);
intent.putExtra(EXTRA_MESSAGE, videoinfo);
StoredVideo.this.startActivity(intent);
}
};
public void removeMedia(String filename) {
File existingFile = new File("\"" + filename + "\"");
existingFile.delete();
Toast.makeText(StoredVideo.this, "File " + filename + " deleted", Toast.LENGTH_LONG).show();
ContentResolver resolver = StoredVideo.this.getContentResolver();
resolver.delete(Video.Media.EXTERNAL_CONTENT_URI, Video.Media.DATA + "=?", new String[]{filename});
}
public class VideoAdapter extends BaseAdapter {
private Context vContext;
public VideoAdapter(Context c) {
vContext = c;
}
public int getCount() {
return count;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public void deleteItem(int position) {
}
public View getView(int position, View convertView, ViewGroup parent) {
System.gc();
ViewHolder holder;
String id = null;
convertView = null;
if (convertView == null) {
convertView = LayoutInflater.from(vContext).inflate(
R.layout.listitem, parent, false);
holder = new ViewHolder();
holder.txtTitle = (TextView) convertView
.findViewById(R.id.txtTitle);
holder.thumbImage = (ImageView) convertView
.findViewById(R.id.imgIcon);
video_column_index = videocursor
.getColumnIndexOrThrow(MediaStore.Video.Media.DISPLAY_NAME);
videocursor.moveToPosition(position);
id = videocursor.getString(video_column_index);
video_column_index = videocursor
.getColumnIndexOrThrow(MediaStore.Video.Media.SIZE);
videocursor.moveToPosition(position);
holder.txtTitle.setText(id);
String[] proj = { MediaStore.Video.Media._ID,
MediaStore.Video.Media.DISPLAY_NAME,
MediaStore.Video.Media.DATA };
@SuppressWarnings("deprecation")
Cursor cursor = managedQuery(
MediaStore.Video.Media.EXTERNAL_CONTENT_URI, proj,
MediaStore.Video.Media.DISPLAY_NAME + "=?",
new String[] { id }, null);
if(cursor.moveToFirst()) {
long ids = cursor.getLong(cursor
.getColumnIndex(MediaStore.Video.Media._ID));
ContentResolver crThumb = getContentResolver();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 1;
Bitmap curThumb = MediaStore.Video.Thumbnails.getThumbnail(
crThumb, ids, MediaStore.Video.Thumbnails.MICRO_KIND,
options);
holder.thumbImage.setImageBitmap(curThumb);
curThumb = null;
}
}
return convertView;
}
}
static class ViewHolder {
TextView txtTitle;
TextView txtSize;
ImageView thumbImage;
}
}
答案 0 :(得分:1)
你不应该每次将null分配给convertView
convertView = null;
if (convertView == null) {
删除convertView = null
。摆脱System.gc();
答案 1 :(得分:0)
让我们看看如何优化:
避免花费更多时间或记忆的操作
不要从getView调用managedQuery(),这会严重影响性能。而你正在那里创建缩略图。如果我需要更具响应性的ListView,我不会这样做。如果您需要它们,请转到AsyncTask。
重复使用视图
默认情况下,适配器会在getView调用期间回收视图,以避免不必要的对象创建。哎呀!去吧。这很简单。
View v = convertView;
if(v == null) {
//inflate view
}
// do the rest
包含ViewHolder模式
ViewHolder模式将平滑性带入ListView。如果你想要时尚的滚动,请阅读
http://developer.android.com/training/improving-layouts/smooth-scrolling.html
http://www.vogella.com/tutorials/AndroidListView/article.html
PS: System.gc()调用不是释放内存的最佳选择。让我们看看Android Doc所说的内容,
System.gc()向VM表明运行垃圾收集器是个好时机。请注意,这只是一个提示。无法保证垃圾收集器实际运行。 的