序言
清明时节雪纷纷
鄙人生性畏寒冷
宅卧室中空寂聊
如何解
遂写此音乐播放的大体结构
正题
整体的框架
项目地址:https://github.com/SilentHiKing/HuMusicPlayer
- Model
在/data/data/com.android.providers.media/databases/目录下有数据库,存放有本地音乐的信息。
系统封装的有ContentProvider
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI
获取后封装成MusicInfo存入集合 - View
SwipeRefreshLayout+RecyclerView实现刷新
ViewPager+AppBarLayout+TabLayout 实现分页(此还未集成) - 音乐播放
另起一个进程开启一个Service,定义IPlayController,使用AIDL实现跨进程通信实现对MediaPlayer控制- MediaPlayer 播放音乐
- MediaSessionCompat 耳机、蓝牙、锁屏界面控制功能监听
- AudioManager 音频焦点得失监听
- 参数(单个音乐路径,播放模式)
注意:
媒体播放涉及到监听,因为是跨进程的:
1、使用RemoteCallbackList注销监听
2、跨进程参数需要序列化
3、监听回调是在Binder线程池中,涉及到UI更新需切到UI线程
Inter.Stub.asInterface获得的IBinder方法调用是线程挂起的,建议在子线程中使用。(个人使用的是HandlerThread)
此应用尝试采用mvp和Rxjava异步框架
- mvp开发模式个人的理解,这个思想就是面向接口编程,通过接口在presenter处理逻辑,m和v没有交集,但监听的处理有很多都是在更新UI,代码多了,结构容易乱
- Rxjava会简单使用,待深入
后续
疑惑点:
1、 播放器另开一个进程的好处,后台一清理还是会停止播放
2、 service如果非私有进程会apk安装不上手机(:去掉)
报的错:
Unknown failure (at android.os.Binder.execTransact(Binder.java:677))
Error while Installing APKs
Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e);
-----------------------------------------------------------------------------------------------
<service
android:name=".music_service.PlayService"
android:enabled="true"
android:exported="true"
android:process=":MusicPlayService">
3、AIDL参数Song在实现序列化的同时,也必须在aidl文件夹下建相同的目录的Song.aidl吗
待开发:
1、 分页ViewPager
2、增加列表播放功能,仿照"本地媒体.db"再增加字段(播放列表ID,是否网络歌曲),自定义到ContentProvider供MusicService访问,使CS播放列表同步
3、 优化事件驱动逻辑,及全局变量
ps:
羡慕纸上谈兵的赵括,其人思维清晰有条理,而且能得到重用。言兵事,以天下莫能当,实乃我辈楷模,其父奢曰:“兵,死地也”。
开发亦是此理,然思路尤为重要,谨记之
附图一张,北京四月的雪:
无法缩放?