学习Android自己的第一个应用

    学习Java有一年多的时间了,从J2SE学到J2EE。之前也做了几个J2EE的项目,但做了些项目之后,发现自己对web这一块,用J2EE进行开发并不是那么的感兴趣。而Android使用Java开发,所以自然而然的转到了Android上来,说起来,也是更喜欢用J2SE一些。

    月初的时候,买了本Android的书系统的学习了一下,加上之前有一点点这方面的经验,半个月的时间把书看完了。在看书的过程中,便把自己想做的一些应用记了下来,第一个想做的便是已经完成的音乐播放器。在此记录下完成过程中遇到的一些问题以及自己学到的知识。

    先说一下音乐播放器的功能:进入播放器后,提供了本地歌曲,在线歌曲两种方式。选择本地歌曲后,可以扫描SD卡下的音乐文件,选择要播放的音乐开始播放。其中可以调节音量,调节播放进度并有时间显示,播放/暂停歌曲,播放上/下一曲,当前歌曲播放完后自动播放下一曲。在线歌曲则是让手机端访问服务器,获得服务器中的歌曲信息后选择歌曲进行播放。下面说一下遇到的一些问题,由于音乐使用Service进行播放,所以需要让Activity与Service进行通信,一开始使用的是bindService()方法,但是当退出当前的Activity时,则音乐也将停止播放,即Service也没有运行了。后来查看API后解决了问题。API中对bindService()方法的描述如下:

Connect to an application service, creating it if needed. This defines a dependency between your application and the service. The given conn will receive the service object when its created and be told if it dies and restarts. The service will be considered required by the system only for as long as the calling context exists. For example, if this Context is an Activity that is stopped, the service will not be required to continue running until the Activity is resumed.

正如最后一句所说,如果当前的Activity停止了,那么这个服务将不会继续运行,直到这个Activity被恢复。如此一看,出现上述问题是自然而然的了。解决方法是在bindService()调用之前加上startService()。来看看API中对于startService()方法的说明:

Using startService() overrides the default service lifetime that is managed by bindService(Intent, ServiceConnection, int): it requires the service to remain running until stopService(Intent) is called, regardless of whether any clients are connected to it. Note that calls to startService() are not nesting: no matter how many times you call startService(), a single call to stopService(Intent) will stop it.

使用startService()方法覆盖了通过bindService()调用的Service的默认生命周期,即可以实现即时在Activity退出之后Service仍然运行。

    解决了这个问题之后,之后便要实现点击相应的歌曲后进入歌曲播放的Activity并用Service进行播放音乐。一开始我是在Activity与Service连接成功后都会调用一次重新播放的方法(播放音乐的方法是写在onServiceConnected()回调方法中的),但是这样用户体验很不好:如果要播放的歌曲就是当前正在播放的歌曲,则将导致这首歌重新开始播放。加入isPlaying()的判断后,能使一首歌持续播放完,但是又导致点击不同的歌曲时不能切换。最后的解决办法是:根据service的生命周期,每次调用starService()时都会触发onStartCommand()方法,通过重写onStartCommand()方法根据当前是否为第一次开启service,如果是,则将播放路径设为当前路径。若不是,则说明正在播放音乐,将用户想要播放的音乐与目前正在播放的音乐路径比较,若相同,则让音乐继续播放,不做改变。若路径不相同,则将player reset,重新装入当前音乐的路径并播放。其实写完后再来看,还是可以将音乐的开始播放写在onServiceConnected()回调方法中的,不过写在Service的onStartCommand()中更加合理。整个调用过程是:先触发Activity的onCreate()方法,调用startService()时触发Service的onCreate()->onStartCommand(),调用bindService()时触发Service的onBind()以及Activity的回调方法onServiceConnected()。即整个过程为:onCreate()(Activity)->onCreate()(Service)->onStartCommand()->onBind()->onServiceConnected()。

    还学到的一点是关于Android布局文件的,Android中的布局是用xml文件完成的,所以掌握好各种资源的xml文件的编写也是很重要的一点。之前一对android:layout_gravit和android:gravity区别不开,布局的时候也有点乱试的感觉。之后写了一个单纯的布局文件测试了一下,再加上schema中的解释:

android:gravity——Specifies how to place the content of an object, both on the x- and y-axis, within the object itself.

也就是该View下包含的子view的摆放方式。而android:layout_gravity:

Standard gravity constant that a child can supply to its parent. 

也就是该View相对于其父view的摆放方式。了解了二者的区别后,便可以更轻松进行布局了。

    写了一大段,纯当做是一个总结。也是在博客园的第一篇博客,接下来会继续写几个小应用,也就当做是练练手,能够更加的熟悉Android的开发。呵呵,下面放一点播放器的图片吧,见笑了。

            






posted @ 2011-10-31 22:44  yohey  阅读(587)  评论(1编辑  收藏  举报