2013-09-24 3 views
7

Dopo aver letto "Media Playback" e "MediaPlayer" di documenti Android, sono ancora confuso e ho bisogno di un consiglio esperto sul metodo sovraccarico setDataSource.MediaPlayer setDataSource necessita di consigli sulle best practice

Sto utilizzando MediaPlayer in un componente Service nel mio progetto che diventerà un foregroundService durante la riproduzione di musica. Ho il mio file musicale (.mp3) nella cartella res/raw del mio apk. Per iniziare a giocare, so che devo preparare l'oggetto MediaPlayer. Poiché i servizi nelle applicazioni Android utilizzano per impostazione predefinita singolo processo e thread principale, non voglio che i miei utenti ottengano ANR mentre MediaPlayer si prepara (pensa se il file multimediale nella cartella raw ha una dimensione grande). Quindi io uso prepareAsync anziché prepare (sincronizzazione). Quindi non posso usare:

mp = MediaPlayer.create(context, R.raw.myfile); 

Perché questo richiede già prepare() internamente ma non prepareAsync(). Quindi, in pratica ho due opzioni (due da quattro):

Uri myUri = Uri.parse("android.resource://" + context.getPackageName() + "/" + R.raw.myfile); 
mp.setDataSource(context, myUri); 

o

AssetFileDescriptor afd = context.getResources().openRawResourceFd(R.raw.myfile); 
mp.setDataSource(fd.getFileDescriptor()); 
afd.close(); 

dopo aver usato uno di loro posso semplice utilizzo:

mp.prepareAsync(); 

E finalmente le mie domande sorgono che "compresi questi diversi metodi, qual è l'opzione migliore? Ci sono dei benefici uno sopra l'altro? Mi manca qualcosa?"

+0

Personalmente, mi piace l'ultimo metodo, dal momento che non utilizza le stringhe nel codice. Non lo so ora, se questo conta tanto di un "beneficio", comunque. – Geobits

+0

@Geobits, evitare stringhe costanti nel codice è una buona pratica come so, ma 'FileDescriptor' è ciò che Android preferisce per i file locali. Grazie per il tuo commento. e ti suggerisco di leggere il mio commento sulla risposta accettata. –

risposta

7

Non ci sono reali vantaggi per i vari modi di chiamare create o setDataSource. I metodi statici create non fanno molto altro che chiamare setDataSource e prepare. I vari metodi setDataSource si chiamano internamente. Alla fine si riducono a due possibili chiamate native, una con una stringa che descrive un URI remoto e un'altra con un descrittore di file locale. Ci può essere un leggero vantaggio in termini di prestazioni nella creazione del descrittore di file da solo, ma non sarà apprezzabile nel contesto.

Per la riproduzione di file locali, come si sta dimostrando nel codice, è sufficiente chiamare il prepare (oi metodi statici create) non è affatto una cattiva pratica. Il giocatore sottostante non dovrebbe avere problemi a determinare i metadati rilevanti e tornare velocemente indipendentemente dalla dimensione del file. Il metodo prepareAsync è più utile per i flussi di rete, in cui un numero qualsiasi di situazioni potrebbe causare un ritardo imprevisto. Se stai progettando un lettore per scopi generici, usare il metodo prepareAsync sarebbe la strada da percorrere, ma se stai semplicemente giocando a risorse non funzionanti non dovrebbe fare alcuna differenza. La varietà di metodi forniti è semplicemente una questione di convenienza (prendere nota di javadoc per create).

+0

dopo aver letto la tua risposta, ho esaminato il [framework android] (https://github.com/android/platform_framework_base/blob/master/media/java/android/media/MediaPlayer.java) e ho capito cosa stai dicendo.Ho visto i metodi 'private native void _setDataSource' e ho notato che' setDataSource (FileDescriptor fd, long offset, long length) 'metodo è più comune per l'accesso locale. Ho dedotto grossolanamente 'FileDescriptor's per local e' Uri's per scopi remoti (stream). –