android music开发笔记
1.启动分析
工程目录 project/packages/apps/Music在music的AndroidManifest.xml文件中,MusicBrowserActivity的intentfilter中定义了
“<category android:name="android.intent.category.LAUNCHER" />”
表明MusicBrowserActivity是music启动时首先调用的activity
2.音乐播放器代码结构
Android源码的Music应用相关代码不算多,packages/apps/Music是关于UI界面的,\packages\providers\MediaProvider关于数据库的,packages/apps/MusicFX是音频效果控制面板。数据库文件放在data/data/com.android.providers.media, 这里面有两个或更多个.db文件,external是外部数据库,记录着Music里显示的那些歌曲,internal是内部数据库,存放着系统铃声文件。根据sd的不同,每次.db文件名字也不同,一张sd卡对应的一个文件。代码方面只有com.android.music一个包,常用的几个类如下:几个关于列表显示的类,下面这些类的显示都用到track_list_item_common.xml这个布局文件,充分体现最大程度复用代码的原则。
MusicBrowserActivity.java 主控制界面
TrackBrowserActivity.java 音乐列表界面
PlaylistBrowserActivity.java 播放列表界面
AlbumBrowserActivity.java 专辑浏览界面
ArtistAlbumBrowserActivity.java 艺术家浏览界面
这两个应该是Music应用中最重要的类了,音乐播放器吗,没播放界面怎么行。
MediaPlaybackActivity.java 音乐播放界面
MediaPlaybackService.java 音乐播放器服务
下面这些都是对话框形式呈现出来的。
RenamePlaylist.java 重命名播放列表界面
CreatePlaylist.java 新建播放列表界面
DeleteItems.java 删除提示框界面
ScanningProgress.java 音乐描扫进度显示界面
MediaAppWidgetProvider.java Widget实现类
MusicPicker.java 音乐选择界面,这是给其它应用程序调用的界面。
MusicUtils.java 播放器公共方法类
ActivityMusic.java
均衡器,音频效果控制面板
3. 扫描sdcard卡读取音乐文件
准确的说应该是媒体文件的扫描,音乐只是其中的一部分。这部分主要包括mediaScannerService,Mediaprovider和MediaScannerReceiver三个类,开机的的时候会收到ACTION_BOOT_COMPLETED消息后启动内部存储扫描工作,而收到MEDIA_MOUNT会扫描SD卡。这里只是简单的说下的流程并不深入讨论,我们重点关心扫描后在把文件信息写到数据库的那个动作。如果仔细看MediaScanner.java的代码,会发现下面这段注释,
- * Java MediaScannerService calls
- * Java MediaScanner scanDirectories, which calls
- * Java MediaScanner processDirectory (native method), which calls
- * native MediaScanner processDirectory, which calls
- * native MyMediaScannerClient scanFile, which calls
- * Java MyMediaScannerClient scanFile, which calls
- * Java MediaScannerClient doScanFile, which calls
- * Java MediaScanner processFile (native method), which calls
- * native MediaScanner processFile, which calls
- * native parseMP3, parseMP4, parseMidi, parseOgg or parseWMA, which calls
- * native MyMediaScanner handleStringTag, which calls
- * Java MyMediaScanner handleStringTag.
- * Once MediaScanner processFile returns, an entry is inserted in to the database.
4. 如何播放音乐
上面音乐也写到数据库了,也能列表显示,如何播放呢?mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(path);
mMediaPlayer.prepare();
mMediaPlayer.start();
对于上层应用就是这样,new出MediaPlayer对象,设好路径,prepare()和start()就没事了,其它的都交给系统了,不过后面的事还是很多的,android的audio系统 也算比较复杂的一部分了。整个audio系统主要由负责输入AudioRecord、负责输出AudioTrack、负责混音的AudioFlinger和策略控制AudioPolicyService四个部分。播放音乐的时候 setDataSourcet()、start()之后会在MediaPlayService的open函数创建AudioTack对象。AudioTrack的作用是要把它的数据发给对应的设备去输出(比如蓝牙耳机或扬声器),在输出之前它需要知道要找哪个设备,根据什么呢?根据流类型(STREAM_ALARM、STREAM_MUSIC、STREAM_RING、STREAM_SYSTEM和STREAM_VOICE_CALL)先找到对应的路由策略,这也是AudioPolicyService, AudioPolicyManagerBase存在的原因,再根据路由策略选择设备, 依据设备信息返回一个的线程索引号给 AudioTrack作为参数CreatTrack找到AudioFlinger合适工作线程(mixerThread or DupicatiingThread)来把数据发给对应的音频输出设备。整个过程还是蛮复杂的,这里只描述了大概流程。代码里面也是故事多多,想完全掌握需要花费些时间。
参考文档: