編輯:關於android開發
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":"AgainstTheGrain","singer":"Akon","mp3":"music/101.mp3"},
{"name":"EntreToiEtMoi","singer":"MathieuEdward","mp3":"music/102.mp3"}]
好了,我們的簡易服務器已經完成了。
我們的接口就是:
http://localhost/music/music.json
目錄如下:
2.新建項目以及文件
與時俱進,我們使用谷歌前不久發布的AndroidStudio2.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
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數據 } };
//調用後會執行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=" "裡。這樣手機端就可以正常連接電腦的服務器了。
到這裡文章就到此結束了,感謝大家支持。: )
Android logcat,androidlogcatlogcat是Android中一個命令行工具,可以用於得到程序的log信息。 基本命令 logcat使用方法如下所
android源碼解析之(五)--)Log相關介紹 這裡面基本都是android framework層的源碼了。而且最近發現了一個比較不錯的github插件:OctoTr
Android打造帶透明圓弧的ImageView,androidimageview 這幾天因為項目需求,需要在ImageView上面疊加一層透明圓弧,並且在沿著圓弧的方
android:Activity啟動模式之singleTask(二) 先看一下standard啟動模式的說明: 只有一個實例,在同一個應用程序中啟動他的時候,若不存在