2013-09-24 12 views
7

"Po przeczytaniu" Android Documentations "nadal jestem zdezorientowany i potrzebuję doœwiadczonej porady na temat przeciążonej metody setDataSource.MediaPlayer setDataSource wymaga porady dotyczącej najlepszych praktyk.

Używam komponentu MediaPlayer w komponencie Service w moim projekcie, który będzie odtwarzany w postaci foregroundService. Mam plik muzyczny (.mp3) w folderze res/raw mojego apk. Aby rozpocząć grę, wiem, że muszę przygotować obiekt MediaPlayer. Ponieważ usługi w aplikacjach na Androida domyślnie używają pojedynczego procesu i głównego wątku, nie chcę, aby moi użytkownicy otrzymywali ANR podczas gdy MediaPlayer przygotowuje się sam (myślę, że plik multimedialny w folderze raw ma duży rozmiar). Następnie używam prepareAsync zamiast prepare (Synchronizacja). Więc nie mogę używać:

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

Bo to już nazywa prepare() wewnętrznie ale nie prepareAsync(). Więc w zasadzie mam dwie opcje (dwa z czterech):

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

lub

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

po użyciu jednego z nich proste użycie mogę:

mp.prepareAsync(); 

I wreszcie moje pytania powstać że "włączając te różne metody, która jest najlepszą opcją? Czy są jakieś korzyści z drugiej strony? Czy czegoś brakuje?"

+0

Osobiście lubię ostatnią metodę, ponieważ nie używa ona ciągów w kodzie. Nie wiem teraz, czy to liczy się z "korzyścią". – Geobits

+0

@Geobits, unikanie stałych łańcuchów w kodzie jest dobrą praktyką, ponieważ wiem, ale 'FileDescriptor' jest tym, co android preferuje dla plików lokalnych. Dzięki za komentarz. i proponuję przeczytać mój komentarz dotyczący zaakceptowanej odpowiedzi. –

Odpowiedz

7

Nie ma żadnych rzeczywistych korzyści dla różnych sposobów wywoływania create lub setDataSource. Statyczne metody create nie mają większego znaczenia niż wywołanie setDataSource i prepare. Różne metody setDataSource wywołują się wewnętrznie. W końcu sprowadzają się do dwóch możliwych wywołań natywnych, jedna z ciągiem opisującym zdalny identyfikator URI i inny z lokalnym deskryptorem pliku. Może zaistnieć niewielka przewaga wydajności przy tworzeniu deskryptora pliku, ale nie będzie to miało znaczenia w kontekście.

Do lokalnego odtwarzania plików, jak pokazano w swoim kodzie, po prostu wywołanie prepare (lub metod statycznych create) nie jest wcale złym zwyczajem. Odtwarzacz nie powinien mieć problemu z określeniem odpowiednich metadanych i szybkim powrotem, bez względu na rozmiar pliku. Metoda prepareAsync jest bardziej przydatna w przypadku strumieni sieciowych, w których dowolna liczba sytuacji może spowodować nieoczekiwane opóźnienie. Jeśli projektujesz odtwarzacza ogólnego przeznaczenia, to metoda do zrobienia, ale jeśli po prostu grasz w surowe aktywa, nie powinna to mieć znaczenia. Różnorodność dostarczanych metod jest po prostu kwestią wygody (należy zwrócić uwagę na javadoc dla create).

+0

po przeczytaniu odpowiedzi, zajrzałem do [platformy android] (https://github.com/android/platform_frameworks_base/blob/master/media/java/android/media/MediaPlayer.java) i zrozumiałem, co mówisz.Widziałem metody 'private native void _setDataSource' i zauważyłem metodę' setDataSource (FileDescriptor fd, long offset, long length) ', która jest bardziej powszechna w przypadku dostępu lokalnego. Z grubsza wydedukowałem "FileDescriptor's dla lokalnych i' Uri' dla celów zdalnych (stream). –

Powiązane problemy