{"id":21990094,"url":"https://github.com/skyhacker2/mvcplayer","last_synced_at":"2025-04-30T12:13:15.712Z","repository":{"id":32112214,"uuid":"35684591","full_name":"skyhacker2/MVCPlayer","owner":"skyhacker2","description":"Android MVC Simple Music Player","archived":false,"fork":false,"pushed_at":"2015-05-15T16:30:46.000Z","size":257,"stargazers_count":10,"open_issues_count":1,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-04-13T08:18:46.427Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/skyhacker2.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-05-15T16:29:26.000Z","updated_at":"2021-12-30T07:39:27.000Z","dependencies_parsed_at":"2022-09-22T23:51:41.897Z","dependency_job_id":null,"html_url":"https://github.com/skyhacker2/MVCPlayer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skyhacker2%2FMVCPlayer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skyhacker2%2FMVCPlayer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skyhacker2%2FMVCPlayer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/skyhacker2%2FMVCPlayer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/skyhacker2","download_url":"https://codeload.github.com/skyhacker2/MVCPlayer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227200342,"owners_count":17746900,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-29T19:37:11.995Z","updated_at":"2024-11-29T19:37:12.583Z","avatar_url":"https://github.com/skyhacker2.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"#MVCPlayer\n\n我尝试在android上使用MVC模式来开发一个音乐播放器。\n\n##什么是MVC\n[来自维基百科](http://zh.wikipedia.org/zh/MVC)\n\n1. 控制器 Controller - 负责转发请求，对请求进行处理。\n2. 视图 View - 界面设计人员进行图形界面设计。\n3. 模型 Model - 程序员编写程序应有的功能（实现算法等等）、数据库专家进行数据管理和数据库设计(可以实现具体的功能)。\n\n那么在android上，Activity就是Controller了。\n\n##划分职责\n1. activity负责处理view的事件和获取模型数据并刷新视图。\n2. view只负责显示\n3. model就是数据部分，不能更新view，数据改变必须通过activity更新view。\n\n##设计我们的播放器\n\n###Models\n\n1. Music - 代表一首歌曲，有歌名、路径、歌手等信息\n2. MusicPlayer - 播放器，我们的逻辑处理部分。\n\n为什么播放音乐不在Activity里面做呢？\n\n播放音乐是Model的一部分，而不是Activity的一部分。\n\n我认为模型代表what it is?\n\n所以播放器是一个model，我设计一个播放器类来封装播放音乐的逻辑。\n\n*MusicPlayer.java*\n\n```\npublic class MusicPlayer {\n    public interface PlayerListener {\n        void onPlay();\n        void onPause();\n        void onResume();\n        void onPlayNext();\n        void onPlayPrev();\n        void onProgressUpdate(int progress);\n    }\n\n    private static MusicPlayer sMusicPlayer;\n    private List\u003cMusic\u003e mPlayList;          // 播放列表\n    private boolean mPlaying;               // 是否正在播放\n    private int mCurrentIndex;              // 目前播放的位置\n    private int mCurrentProgress;           // 播放进度\n    private MediaPlayer mMediaPlayer;       // 播放器\n    private PlayerListener mListener;       // 监听器\n    private Timer mTimer;                   // 计时器\n    private int mTotalTime;                 // 播放时间\n    public static MusicPlayer getInstance(){...}\n    public void play(final int index) {...}\n    public void pause() {...}\n    public void resume() {...}\n    public void playNext() {...}\n    public void playPrev() {...}\n```\n\n为了当播放器内部状态改变的时候通知Activity，我定义了一个PlayerListener\n\n## Views\n视图就是xml文件，没什么好说的了。\n\n##Activity\n\nActivity里面包含了视图对象和播放器对象。\n\n首先通过ContentResolver获取手机里面的歌曲，\n然后放到播放器里面，同时放到播放列表的adapter里面。\n\n```\nmMusicPlayer = MusicPlayer.getInstance();\nmMusicPlayer.setPlayList(getPlayList());\nmMusicPlayer.setListener(getPlayerListener());\n\nmMusicListAdapter = new MusicListAdapter(this, getPlayList());\nmMusicListView.setAdapter(mMusicListAdapter);\n```\n\n当点击列表时，告诉播放器播放音乐。\n\n```\nmMusicListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {\n    @Override\n    public void onItemClick(AdapterView\u003c?\u003e parent, View view, int position, long id) {\n        mMusicPlayer.play(position);\n    }\n});\n```\n\n这时候播放器的状态改变，`onPlay`方法被调用，通知Activity更新视图：\n\n```\npublic MusicPlayer.PlayerListener getPlayerListener() {\n    if (mPlayerListener == null) {\n        mPlayerListener = new MusicPlayer.PlayerListener() {\n            @Override\n            public void onPlay() {\n                updateUI();\n            }\n\n            @Override\n            public void onPause() {\n                updateUI();\n            }\n\n            @Override\n            public void onResume() {\n                updateUI();\n            }\n\n            @Override\n            public void onPlayNext() {\n                updateUI();\n            }\n\n            @Override\n            public void onPlayPrev() {\n                updateUI();\n            }\n\n            @Override\n            public void onProgressUpdate(int progress) {\n                updateUI();\n            }\n        };\n    }\n    return mPlayerListener;\n}\n```\n\n整个过程是：View发出action，controller改变model，model通知controller状态改变，controller更新view。\n\n#小结\n\nMVC模式使我们更好地设计软件，各部分的职责分工明确。Model和View相对独立，易于更改。例如我不想在Activity里面播放音乐，完全可以把MusicPlayer放到Service上去播放，而且播放代码一句也不用改。\n\n![image](./images/Screenshot_2015-05-16-00-26-25.png)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskyhacker2%2Fmvcplayer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fskyhacker2%2Fmvcplayer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fskyhacker2%2Fmvcplayer/lists"}