• Andriod小项目——在线音乐播放器


    转载自:

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

    Andriod小项目——在线音乐播放器


    Android在线音乐播放器

    从大一开始就已经开始自学JavaAndroid了,到现在差不多有一年了。

    终于到了开始做项目实战的阶段了。就先DIY个在线音乐播放器。


    实现了以下功能:

    这个播放器可以从本机电脑搭建的简易服务器里异步读取并解析json数据,播放音乐,实现音乐切换时间显示,以及显示播放进度


    程序有三个界面,启动画面,音乐列表,播放器页面,可以通过音乐列表点击进入到播放界面。


    这篇文章只大概写了一下实现的思路,描述了一些关键的地方。

    文章最后还提供了源代码,可以在文章结尾处  下载




    这是播放界面效果图:


     





    具体思路如下:共6步


    1.搭建简易服务器和接口设计

    我们需要自己搭建一个简易的服务器,以便我们在手机客户端访问我们电脑目录中的音乐文件。

    这里我们选择的是XAMPP套件,我们使用Apache服务器。

    当然你选择电脑自带的IIS也是可以的,你可在控制板中开启它。在这里就不再多说了。

    如果你和我一样使用了XAMPP,打开X:xampphtdocs 

    这里是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







  • 相关阅读:
    JDBC连接效率问题
    如何配置Filter过滤器处理JSP中文乱码(转)
    Servlet生命周期与工作原理(转)
    ANR触发原理
    SystemServer概述
    Zygote总结
    ART、JIT、AOT、Dalvik之间有什么关系?
    谈谈android缓存文件
    Activity启动过程全解析
    tombstone问题分析
  • 原文地址:https://www.cnblogs.com/sunyl/p/5469529.html
Copyright © 2020-2023  润新知