2016-12-26 1 views
0

Actuellement j'essaye de construire un lecteur de musique android à part entière. Je charge toutes les chansons, les artistes, les listes de lecture etc de mediastore chaque fois que l'application est chargée et précédemment pas présent dans RAM. Cette approche, bien que reflétant les changements de mediastore entre les charges d'application augmente considérablement le temps de chargement. Comment dois-je procéder pour obtenir des temps de chargement agréables et tenir compte des changements de données? Merci d'avance.Comment les lecteurs multimédias android natifs rendent les données persistantes et reflètent les changements

+0

Pourquoi ce auriez-vous besoin de charger toute la musique, etc. Vous simplement chercher dont vous avez besoin et quand vous en avez besoin. – Theo

+0

Supposons que j'ai un viewpager avec des sections de chanson, album, liste de lecture, genre et ainsi de suite. Au strict minimum, j'ai besoin du nom et de l'identifiant de chaque catégorie. Encore je dois interroger la base de données entière, seulement le champ de filtrage sera rétréci. Maintenant, si je fais une requête chaque fois que je balaye le viewpager, l'interface utilisateur sera-t-elle lisse? J'ai 7,5 Go de chansons btw. –

Répondre

1

Pour passer un curseur sur recyclerview adaptateur dans le Fragment mettre en œuvre LoaderManager

public class LayoutFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> 

      getLoaderManager().initLoader(0, null, LayoutFragment.this); 
    mAdapter = new LayoutAdapter(getActivity(),mRecyclerView,mLayoutId, mcursor); 
    mRecyclerView.setAdapter(mAdapter); 

En outre, dans votre adaptateur, réglez la signature

 public LayoutAdapter(Context context, RecyclerView recyclerView, int layoutId, Cursor c) { 
    mContext = context; 
    mCursor = c; 
    mRecyclerView = recyclerView; 
    mLayoutId = layoutId; 
} 

et ajoutez quelques méthodes parce que vous avez besoin à l'intérieur du fragment

 @Override 
public int getItemCount() { 
    if(mCursor!=null) { 
     return mCursor.getCount(); 
    }else{ 
     return 0; 
    } 
} 

public void swapCursor(Cursor newCursor) { 
    if (newCursor == mCursor) { 
     return; 
    } 

    if (newCursor != null) { 
     mCursor = newCursor; 
     mRowIDColumn = mCursor.getColumnIndexOrThrow("_id"); 
     mDataValid = true; 
     // notify the observers about the new cursor 
     notifyDataSetChanged(); 
    } else { 
     notifyItemRangeRemoved(0, getItemCount()); 
     mCursor = null; 
     mRowIDColumn = -1; 
     mDataValid = false; 
    } 
} 

et Fragment

 @Override 
public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
    switch (id) { 
     case LOADER: 
      Uri uri = MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI; 
      final String criteria = null; 
      String[] columns = { 
        MediaStore.Audio.Playlists._ID, 
        MediaStore.Audio.Playlists.NAME, 
      }; 
      return new CursorLoader(getActivity(), uri, columns, criteria, null, MediaStore.Audio.Playlists.NAME + " ASC"); 
     default: 
      return null; 
    } 

} 

@Override 
public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
    mAdapter.swapCursor(data); 
    mcursor=data; 
    mAdapter.notifyDataSetChanged(); 
} 

@Override 
public void onLoaderReset(Loader<Cursor> loader) { 
    mAdapter.swapCursor(null); 
    mcursor=null; 
    mAdapter.notifyDataSetChanged(); 
} 
0

J'utilise une approche viewpager dans mon application New Playlist Manager, une pour toutes les pistes, albums et artistes. Pour chacun d'eux, j'ai un fragment dont chacun a un cursorAdapter personnalisé. Je vous donne l'exemple de toutes les pistes: mis en place mes colonnes:

 dataColumns= new String[]{ 
      MediaStore.Audio.Media.TRACK, 
      MediaStore.Audio.Media._ID, 
      MediaStore.Audio.Media.DATA, 
      MediaStore.Audio.Media.ARTIST, 
      MediaStore.Audio.Media.YEAR, 
      MediaStore.Audio.Media.DURATION, 
      MediaStore.Audio.Media.TITLE, 
      MediaStore.Audio.Media.ALBUM, 
      MediaStore.Audio.Media.ALBUM_ID 
    }; 
    sort_order = MediaStore.Audio.Media.TITLE +" ASC"; 

Pour remplir mon listView J'utilise un LoaderManager dans OnViewCreated

getLoaderManager().initLoader(GALLERY_LOADER, null, this); 

et

 @Override 
public Loader<Cursor> onCreateLoader(int loaderID, Bundle bundle) { 
    switch (loaderID) { 
     case GALLERY_LOADER: 
      return new CursorLoader(getActivity(), 
        MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 
        dataColumns, 
        null, null, 
        sort_order); 
     default: 
      return null; 
    } 
} 


@Override 
public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
    mAdapter.swapCursor(data); 
    mAdapter.notifyDataSetChanged(); 
} 
@Override 
public void onLoaderReset(Loader<Cursor> loader) { 
    mAdapter.swapCursor(null); 

} 

Alors Lorsque la vue a été créée, le LoaderManager récupère le curseur nécessaire qui est ensuite transmis à l'adaptateur. Ainsi, pour chacun des fragments, vous ne récupérez que les données dont vous avez besoin. Pour les albums Loader Cursor ressemble:

  public class showallAlbumsFragment extends Fragment implements 
    OnItemClickListener, LoaderManager.LoaderCallbacks<Cursor> 

      dataColumns= new String[]{ 
        BaseColumns._ID, 
        AlbumColumns.ALBUM, 
        AlbumColumns.NUMBER_OF_SONGS, 
        AlbumColumns.FIRST_YEAR, 
        AlbumColumns.ARTIST }; 
    sort_order = AlbumColumns.ALBUM +" ASC"; 




    @Override 
public Loader<Cursor> onCreateLoader(int loaderID, Bundle bundle) { 
    switch (loaderID) { 
     case GALLERY_LOADER: 
      return new CursorLoader(getActivity(), 
        MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI, 
        dataColumns, 
        null, null, 
        sort_order); 

     default: 
      return null; 
    } 
} 

J'espère que cela vous fait aller

+0

Merci, mais j'utilise une vue recycleur au lieu d'une vue en liste et il n'y a pas d'adaptateur de curseur pour la vue recycleur –

+0

Peu importe. Vous devez savoir comment passer le curseur à recyclerview – Theo