Android BaseAdapter滚动速度慢

时间:2014-07-22 15:08:47

标签: android video scroll baseadapter

我正在使用 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;
}

}

2 个答案:

答案 0 :(得分:1)

你不应该每次将null分配给convertView

convertView = null;
if (convertView == null) {

删除convertView = null。摆脱System.gc();

答案 1 :(得分:0)

当您滚动List时,将多次调用ListView适配器的getView()方法。因此,您不应执行任何需要更多时间或更多内存的操作。否则会导致性能下降或崩溃。

让我们看看如何优化:

避免花费更多时间或记忆的操作

不要从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表明运行垃圾收集器是个好时机。请注意,这只是一个提示。无法保证垃圾收集器实际运行。