2014-07-22 102 views
-1

我正在列出設備內存中的視頻,其中BaseAdapter我注意到滾動效果不是很好,很慢。 我應該使用不同的方法來完成這項工作,還是有一種方法可以改進這項工作?Android 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

首先,當您僅使用遊標獲取單個值時,請勿使用managedQuery。然後,在不需要時關閉光標。那麼,使用查詢來獲取每個ID的事實肯定會很慢,因爲您匹配每個視頻的視頻名稱。最後,得到縮略圖也很慢,你應該考慮在asynctask中這樣做。 – njzk2

+0

你不需要一個新的查詢來獲得id,它已經在你的'videocursor'中。 – njzk2

+0

另外,由於您在適配器中使用了光標,因此您可以使用cursoradapter,它可以爲您完成一些工作。 – njzk2

回答

0

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()向虛擬機指示現在是運行垃圾回收器的好時機。請注意,這只是一個提示。不能保證垃圾收集器將實際運行。

+0

謝謝,很好的建議!你知道這個新添加的視頻到這個圖庫出現兩次出現在這個方法列表中嗎? – andreasperelli

1

你應該每次都空不分配給convertView

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

刪除convertView = null。擺脫也System.gc();

+0

我剛剛刪除了2條說明,現在奇怪的是,視頻加載了相同的縮略圖。相反,滾動速度更快。 – andreasperelli

+0

你應該肯定使用CursorAdapter,因爲你正在處理一個遊標 – Blackbelt

+0

有沒有我改變整個代碼? – andreasperelli