轉載自:
http://blog.csdn.net/sunkes/article/details/51189189
Andriod小項目——在線音樂播放器
Android在線音樂播放器
從大一開始就已經開始自學Java和Android了,到現在差不多有一年了。
終於到了開始做項目實戰的階段了。就先DIY個在線音樂播放器。
實現了以下功能:
這個播放器可以從本機電腦搭建的簡易服務器裏異步讀取並解析json數據,播放音樂,實現音樂切換,時間顯示,以及顯示播放進度。
程序有三個界面,啓動畫面,音樂列表,播放器頁面,可以通過音樂列表點擊進入到播放界面。
這篇文章只大概寫了一下實現的思路,描述了一些關鍵的地方。
文章最後還提供了源代碼,可以在文章結尾處 下載。
這是播放界面效果圖:
具體思路如下:共6步
1.搭建簡易服務器和接口設計
我們需要自己搭建一個簡易的服務器,以便我們在手機客戶端訪問我們電腦目錄中的音樂文件。
這裏我們選擇的是XAMPP套件,我們使用Apache服務器。
當然你選擇電腦自帶的IIS也是可以的,你可在控制板中開啓它。在這裏就不再多說了。
如果你和我一樣使用了XAMPP,打開X:\xampp\htdocs
這裏是Apache服務器的根目錄。
我們一會可以通過在瀏覽器輸入localhost訪問到這裏,或者局域網下電腦IP也可以訪問到此處。
我們在htdocs 裏新建文件夾music,接着拷貝幾首音樂到剛剛我們建立的文件夾裏。然後再新建music.json文件和我們的歌曲放在一起。
我們可以開始編輯json了,打開我們剛剛建立的Music.json:
[{"name":"Against The Grain","singer":"Akon","mp3":"music/101.mp3"},
{"name":"Entre Toi Et Moi","singer":"Mathieu Edward","mp3":"music/102.mp3"}]
好了,我們的簡易服務器已經完成了。
我們的接口就是:
http://localhost/music/music.json
目錄如下:
2.新建項目以及文件
與時俱進,我們使用谷歌前不久發佈的Android Studio 2.0作爲開發環境。
打開它新建工程,取一個名字。
然後我們創建一下目錄:
activity---是我們的活動類,我們所所有的活動都在這裏建立
adapter--適配器,保存一些像ListView適配器等
Model--實體類,用於存放Music實體。
Server--服務,我們將把後臺服務代碼建立在這裏
util--工具,我們將設計一些播放音樂會使用的函數等內容,然後把它封裝成類,便於使用
建立完後應如圖所示:
3.設計啓動界面,
啓動畫面,就類似於微信打開時的月球的那個頁面。新建一個SplashActivity
我們需要讓啓動畫面顯示兩秒鐘左右,然後結束這個活動,跳轉到進入主程序。代碼如下:
我們使用Handler類裏的postDelayed方法,第一個參數時一個Runnable接口,
我們直接傳入並實現匿名接口,在run方法裏啓動另一個活動,這一步我們一氣呵成。
public class SplashActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.logo_show_layout); //啓動畫面的代碼: new Handler().postDelayed(new Runnable() { @Override public void run() { startActivity(new Intent(SplashActivity.this,MusicListMainActivity.class)); SplashActivity.this.finish(); } },1500); } }
4.編寫顯示音樂信息的列表活動。
新建MusicListMainActivity
這個活動也就是啓動界面結束以後,啓動的類。這個類將連接服務器,獲取並解析,json數據。顯然這需要線程異步處理,不然網絡連接或阻塞到主線程,從而導致出現 ANR 。
這裏我們使用AsyncTask,AsyncTask有不少缺點大家應該知道,如果可以還是使用java回調來與線程相結合。或者其他方法
我們雖然在這裏使用了AsyncTask,但是還是提供java 線程+接口回調實現的方法:
接口設計:
public interface HttpCallbackListener { void onFinish(String response); void onError(Exception e); }
在HttpUtil工具類裏編寫相關方法:
public static void sendHttpRequest(final String address, final HttpCallbackListener listener) { new Thread(new Runnable() { @Override public void run() { try { ... while ((line = reader.readLine()) != null) { response.append(line); } if (listener != null) { // 回調onFinish()方法 listener.onFinish(response.toString()); } } catch (Exception e) { if (listener != null) { // 回調onError()方法 listener.onError(e); } } finally { if (connection != null) { connection.disconnect(); } } } }).start(); }
然後我們可以在我們需要的地方調用了,傳入相應參數即可,第二個參數是一個匿名接口的實現。
HttpUtil.sendHttpRequest(address, new HttpCallbackListener() { @Override public void onFinish(final String response) { } @Override public void onError(Exception e) { } })
注意在裏還是不能更新UI的,因爲還是屬於子線程裏面。也需要Handler或者runOnUiThread(..)來 實現更新UI
好了,讓我們來看看AsyncTask如何實現這種功能呢:
首先新建HttpResponseHandle類,把它放到Util文件夾裏面,繼承自 AsyncTask<String, Void, String>
AsyncTask這個類使用了Java泛型,第一個參數是執行時傳入的參數,第二個是進度顯示的參數,如果需要顯示進度例如41%,這裏就不能爲空了。第三個參數是異步執行完成後返回類型。
protected String doInBackground(String... params) @Override protected void onPostExecute(String result) { onComplete(result); }
我們繼承之後實現以上這兩個函數,第一個函數是可以進行耗時操作的,因爲android在底層實現了異步線程,第二個函數將在doInBackground結束完成後回調,並傳入doInBackground返回值,這中間操作時自動完成的。這時我們後臺操作已經完成了。我們在HttpResponseHandle 建一個抽象函數public abstract void onComplete(String result),以便實現類似與剛剛用接口回調的效果。
這個抽象函數將接收解析完成的數據,我們稍後會在MusicListMainActivity調用它。
在MusicListMainActivity的實現:
HttpResponseHandle httpResponseHandle = new HttpResponseHandle() { //執行到了onComplete說明我們編寫的異步處理已經成功讀取了數據, //由於是JSON格式的數據,我們可以在onComplete裏開始解析它 @Override public void onComplete(String result) { // 在這裏接受數據,開始解析json數據 } };
我們寫的異步處理是不會自動啓動的,我們需要調用execute()函數:
//調用後會執行doInBackground(),並execute將參數傳給它doInBackground httpResponseHandle.execute("http://192.168.41.3/music/music.json ");
5.服務類的設計思路
服務類通通過接收判斷參數,從而執行不同的操作。
值得注意的是,android服務並不能直接執行耗時操作,還是需要自己另外開啓多線程的。在調用MediaPlay.prepare()是個耗時操作,會導致主線程阻塞。
這裏使用prepareAsync()就好了,不然就得自己開線程了或者其他方法來處理阻塞了。
6.MusicUtil工具類
實現了初始化音樂,音樂的播放,暫停,還實現了實時更新音樂的進度。
更音樂的進度是這樣實現的:
設置自己每秒執行500毫秒的Handler通過發送廣播,通知MusicPlayer進行UI更新。
還有個MusicMediaUtil類可能用不到,這個類可以返回MediaPlayer對象,和new MediaPlayer()效果一樣。設計這個類是因爲在setDataSource切換歌曲時有的時候會報一些錯誤。我參考了許多資料,都說是無關緊要的錯誤(E/MediaPlayer: Should have subtitle controller already set ),就按照StackOverFlow提供的方法處理了。——這類直接使用JAVA的反射,對原代碼稍稍修改一下,這樣就不會出現E/MediaPlayer:
Should have ...的錯誤了。
好了最後說一說項目如何運行呢?
開啓服務器,首先確保,電腦與你的手機在同一個局域網中,最簡單的方法就是它們連接一個同WiFi,
然後電腦按Windows鍵+R 輸入cmd打開命令行,輸入ipconfig ipv4 就是你電腦的IP了,把IP它填入MusicListMainActivity裏面的root=" "裏。這樣手機端就可以正常連接電腦的服務器了。
到這裏文章就到此結束了,感謝大家支持。: )
PS.
初學者文章,大神請輕拍!!
第一次寫關於安卓的博客,大家要多多鼓勵我哈~。
下載地址:
http://download.csdn.net/detail/sunkes/9495726