2013-09-24 24 views
7

Sau khi đọc "Media Playback" và "MediaPlayer" tài liệu android tôi vẫn còn nhầm lẫn và cần tư vấn có kinh nghiệm về phương pháp quá tải setDataSource.MediaPlayer setDataSource cần lời khuyên thực hành tốt nhất

Tôi đang sử dụng MediaPlayer trong thành phần Service trong Dự án sẽ là foregroundService khi phát nhạc. Tôi có tệp nhạc của tôi (.mp3) trong thư mục res/raw của gói ứng dụng của tôi. Để bắt đầu chơi, tôi biết tôi phải chuẩn bị đối tượng MediaPlayer. Bởi vì dịch vụ trong các ứng dụng Android theo mặc định sử dụng quy trình đơn và chủ đề chính, tôi không muốn người dùng của mình nhận được ANR trong khi MediaPlayer tự chuẩn bị (nghĩ rằng nếu tệp phương tiện trong thư mục thô có kích thước lớn). Sau đó, tôi sử dụng prepareAsync thay vì prepare (Đồng bộ). Vì vậy, tôi không thể sử dụng:

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

Bởi vì đây đã kêu gọi prepare() nội bộ nhưng không prepareAsync(). Vì vậy, về cơ bản tôi có hai lựa chọn (hai từ bốn):

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

hoặc

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

sau khi sử dụng một trong số họ đơn giản sử dụng Tôi có thể:

mp.prepareAsync(); 

Và cuối cùng câu hỏi của tôi phát sinh rằng "bao gồm các phương pháp khác nhau này, cái nào là lựa chọn tốt nhất? Có lợi ích nào khác không? Tôi có thiếu gì không?"

+0

Cá nhân, tôi thích phương pháp cuối cùng vì nó không sử dụng chuỗi trong mã. Tôi không phải bây giờ nếu đó là số tiền của một "lợi ích", mặc dù. – Geobits

+0

@Geobits, tránh chuỗi liên tục trong mã là một thực hành tốt như tôi biết nhưng 'FileDescriptor' là những gì android thích cho các tập tin địa phương. Cảm ơn bạn đã bình luận. và tôi đề nghị bạn đọc nhận xét của tôi về câu trả lời được chấp nhận. –

Trả lời

7

Không có bất kỳ lợi ích thực sự nào cho các cách gọi khác nhau create hoặc setDataSource. Các phương pháp tĩnh create không làm nhiều hơn là gọi setDataSourceprepare. Các phương thức setDataSource khác nhau gọi nhau trong nội bộ. Cuối cùng, chúng đun sôi xuống hai cuộc gọi tự nhiên có thể, một với một chuỗi mô tả một URI từ xa và một chuỗi khác với một bộ mô tả tệp cục bộ. Có thể có một lợi thế hiệu suất rất nhỏ để tự tạo bộ mô tả tệp, nhưng nó sẽ không được đánh giá cao trong ngữ cảnh.

Để phát lại tệp cục bộ, như bạn đang minh họa trong mã của mình, chỉ cần gọi prepare (hoặc phương pháp tĩnh create) không phải là một thực tế tồi. Trình phát cơ bản sẽ không gặp sự cố khi xác định siêu dữ liệu có liên quan và trả lại nhanh chóng bất kể kích thước của tệp. Phương thức prepareAsync hữu ích hơn cho các luồng mạng, trong đó bất kỳ số lượng trường hợp nào có thể gây ra một số trễ không mong muốn. Nếu bạn đang thiết kế một máy nghe nhạc có mục đích chung, thì sử dụng phương pháp prepareAsync sẽ là cách để đi, nhưng nếu bạn chỉ đơn giản là chơi nội dung thô thì nó sẽ không tạo ra bất kỳ sự khác biệt nào. Sự đa dạng của các phương pháp được cung cấp chỉ đơn giản là một vấn đề thuận tiện (lưu ý javadoc cho create).

+0

sau khi đọc câu trả lời của bạn, tôi đã xem [khung công tác android] (https://github.com/android/platform_frameworks_base/blob/master/media/java/android/media/MediaPlayer.java) và hiểu những gì bạn nói.Tôi đã thấy các phương thức 'private native void _setDataSource' và nhận thấy phương thức' setDataSource (FileDescriptor fd, long offset, long length) 'là phổ biến hơn cho truy cập cục bộ. Tôi đã suy luận về 'FileDescriptor' cho các mục đích cục bộ và 'Uri' cho các mục đích từ xa (stream). –

Các vấn đề liên quan