Andriod小項目——在線音樂播放器

轉載自:

http://blog.csdn.net/sunkes/article/details/51189189

 

Andriod小項目——在線音樂播放器


Android在線音樂播放器

從大一開始就已經開始自學JavaAndroid了,到現在差不多有一年了。

終於到了開始做項目實戰的階段了。就先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

 







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章