Android(java)学习笔记181:Android 服务的应用,在Activity中实现背景音乐播放

1.在android应用程序里,有一种没有UI的类(android.app.Service)——Service。简单来说,Service是一个 background process(背景程序),通过背景程序,可以实现一些不需要UI的功能,比如播放背景音乐。

下面是一个实现播放背景音乐的例程:

在上个工程的基础上,在Activity中添加音乐播放功能。

在工程中添加一个新类 VoiceService (File->New->Class):

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class MyService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

}

MyService 类继承 android.app.Service,几个有关Service 的重要概念如下:

1). Service 对象以 separated process (单独的线程)的方式执行,这表示 Service 与 UI(Activity)并不在同一个 process 里执行,而是各自在不同的 process 执行。

2). Android应用程序是在 Activity 启动与停止 Service。

3). 重载(override)onStart() 方法(method)在 Service 被启动,执行我们想要的背景功能。

4). 重载 onDestroy() 方法在 Service 被停止时,停止执行中的背景功能。

下面是Service的具体实现:

package com.himi.game2048;

import java.io.IOException;

import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.os.IBinder;

public class VoiceService extends Service {
    private MediaPlayer mp;

    @Override
    public void onCreate() {
        // 初始化音乐资源
        try {
                mp = MediaPlayer.create(this, R.raw.play_music);
                mp.prepare();
        } catch (IllegalStateException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        } catch (IOException e) {
            // TODO 自动生成的 catch 块
            e.printStackTrace();
        }
        super.onCreate();

    }

    @Override
    public void onStart(Intent intent, int startId) {
        // TODO 自动生成的方法存根
        //开始播放音乐
        if(mp != null) {
            mp.start();
            //注册回调函数,音乐播放完毕之后,音乐播放完毕的事件处理
            mp.setOnCompletionListener(new OnCompletionListener() {

                public void onCompletion(MediaPlayer mp) {
                    try {
                        mp.start();
                    } catch (IllegalStateException e) {
                        // TODO 自动生成的 catch 块
                        e.printStackTrace();
                    }

                }
            });

            mp.setOnErrorListener(new OnErrorListener() {

                public boolean onError(MediaPlayer mp, int what, int extra) {
                    try {
                        mp.release();
                    } catch (Exception e) {
                        // TODO 自动生成的 catch 块
                        e.printStackTrace();
                    }
                    return false;
                }
            });

        }

        super.onStart(intent, startId);
    }

    @Override
    public void onDestroy() {
        // 服务停止时停止播放器并且释放资源
        if (mp != null) {
            mp.stop();
            mp.release();
        }
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO 自动生成的方法存根
        return null;
    }

}

至此,一个完整的服务生成,接下来是在Activity中启动服务。

 

2.修改 AndroidManifest.xml

在 Package Explorer 视窗里找到目前 Android 项目的资讯描述档,名称为 AndroidManifest.xml。这是一个用來描述 Android 应用程序「整体资讯」的文件,每个 Android 应用程序项目都会有一个。在这里修改 Androidmanifest.xml 的目的是为了「 Android 应用程序加入一个 Service 类别」,这样才有办法驱动 Service。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.himi.game2048"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="15"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/pciture"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <!-- android:screenOrientation="portrait"手机屏幕是直立的,不会水平放置 -->
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name="com.himi.game2048.VoiceService"
            android:exported="true"
            android:process=":remote" >
        </service>
    </application>

</manifest>

android:exported:

       这个属性用于指示该服务是否能够被其他应用程序组件调用或跟它交互。如果设置为true,则能够被调用或交互,否则不能。设置为false时,只有同一个应用程序的组件或带有相同用户ID的应用程序才能启动或绑定该服务。

android:process:

(1)如果不设置android:process则activity和service属于同一进程。

(2)如果设置android:process=“:remote”  表示创建一个全局的独立进程。不同的应用程序共享该进程。

(3)如果设置android:process=“.remote”  表示在当前应用里,创建一个进程。

3.配置好之后,接下来就是在Activity中添加启动服务代码 Service - startService()

在OnCreate()中添加如下代码:

        Intent intent = new Intent(WebTestActivity.this,yypService.class);
        startService(intent);

Activity 类里有一个 method 叫做 startService:

startService(Intent service)

调用 startService() 即可启动一个 Service ,只是,startService() 的参数是一个「Intent」型,并不是所要启动的类名。「Intent」是一个很像「Event」的类,暂时还没对Intent做深入研究,就先把它当作一个"Event"看吧?

现在,其实已经可以在Activity中播放背景音乐了,但有一个小问题,就是Activity已经被挂起或是被销毁时,背景音乐还是在继续播放的,这也说明Service与Activity是两个不同的进程,我们收下尾,让Activity在OnStop时把背景音乐也停止播放,重载Activity的OnStop:

    @Override
    protected void onStop() {
        // TODO Auto-generated method stub
        Intent intent = new Intent(WebTestActivity.this,yypService.class);
        stopService(intent);
        super.onStop();
    }
时间: 2024-10-08 20:50:43

Android(java)学习笔记181:Android 服务的应用,在Activity中实现背景音乐播放的相关文章

【Android开发学习笔记】【第三课】Activity和Intent

首先来看一个Activity当中启动另一个Activity,直接上代码说吧: (1)首先要多个Activity,那么首先在res-layout下新建一个 Other.xml,用来充当第二个Activity的布局文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu

【Android开发学习笔记】【第五课】Activity的生命周期-上

今天学习Activity当中的七个生命周期函数: 首先得说一个事情,就是在代码当中如果加入了 System.out.println(" ------");之后,如何查看这里面的输出内容 打开之后只输入“Filter Name”和“by Log Tag” 即可 添加成功后可以看到 本次学习主要总结如下: 1.onCreate() Acitivity首次创建时被调用.用于设置Acitivity的布局文件,绑定按钮监听器等一些普通静态操作. 2.onStart() Acitivity对用户可

java学习笔记-0918班马义*,在大雨磅礴中来到尚硅谷

从9月23号在大雨磅礴中来到尚硅谷java培训,已经过去一月有余.五个月的学习路程已走完20%.第一阶段的考试也结束了.北京Java培训和我以往在大学学习的专业有很大不同,这一个多月的学习也让我的文科生思维慢慢转变过来,java很考逻辑思维,如果面向对象的思想有了,学习java就会容易一些.对于编程,我觉得最好的学习方法就是多敲代码,敲到一定程度,代码都是自然而然从指尖流露出来. 通过一个月的学习,我也慢慢找到了自己学习java的方法,每天晚上的自习时间看今天老师的java视频,根据遗忘曲线,如

android开发学习笔记000

使用书籍:<疯狂android讲义>——李刚著,2011年7月出版 虽然现在已2014,可我挑来跳去,还是以这本书开始我的android之旅吧. “疯狂源自梦想,技术成就辉煌.” 让我这个一直梦想走技术流的再疯狂一次.2014.08.06. 直奔主题——>android开发学习笔记001 android开发学习笔记000

java/android 设计模式学习笔记(9)---代理模式

这篇博客我们来介绍一下代理模式(Proxy Pattern),代理模式也成为委托模式,是一个非常重要的设计模式,不少设计模式也都会有代理模式的影子.代理在我们日常生活中也很常见,比如上网时连接的代理服务器地址,更比如我们平时租房子,将找房子的过程代理给中介等等,都是代理模式在日常生活中的使用例子. 代理模式中的代理对象能够连接任何事物:一个网络连接,一个占用很多内存的大对象,一个文件,或者是一些复制起来代价很高甚至根本不可能复制的一些资源.总之,代理是一个由客户端调用去访问幕后真正服务的包装对象

java/android 设计模式学习笔记(14)---外观模式

这篇博客来介绍外观模式(Facade Pattern),外观模式也称为门面模式,它在开发过程中运用频率非常高,尤其是第三方 SDK 基本很大概率都会使用外观模式.通过一个外观类使得整个子系统只有一个统一的高层的接口,这样能够降低用户的使用成本,也对用户屏蔽了很多实现细节.当然,在我们的开发过程中,外观模式也是我们封装 API 的常用手段,例如网络模块.ImageLoader 模块等.其实我们在开发过程中可能已经使用过很多次外观模式,只是没有从理论层面去了解它. 转载请注明出处:http://bl

java/android 设计模式学习笔记(10)---建造者模式

这篇博客我们来介绍一下建造者模式(Builder Pattern),建造者模式又被称为生成器模式,是创造性模式之一,与工厂方法模式和抽象工厂模式不同,后两者的目的是为了实现多态性,而 Builder 模式的目的则是为了将对象的构建与展示分离.Builder 模式是一步一步创建一个复杂对象的创建型模式,它允许用户在不知道内部构建细节的情况下,可以更精细地控制对象的构造流程.一个复杂的对象有大量的组成部分,比如汽车它有车轮.方向盘.发动机.以及各种各样的小零件,要将这些部件装配成一辆汽车,这个装配过

java/android 设计模式学习笔记(一)---单例模式

前段时间公司一些同事在讨论单例模式(我是最渣的一个,都插不上嘴 T__T ),这个模式使用的频率很高,也可能是很多人最熟悉的设计模式,当然单例模式也算是最简单的设计模式之一吧,简单归简单,但是在实际使用的时候也会有一些坑. PS:对技术感兴趣的同鞋加群544645972一起交流 设计模式总目录 java/android 设计模式学习笔记目录 特点 确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 单例模式的使用很广泛,比如:线程池(threadpool).缓存(cache).对

java/android 设计模式学习笔记(7)---装饰者模式

这篇将会介绍装饰者模式(Decorator Pattern),装饰者模式也称为包装模式(Wrapper Pattern),结构型模式之一,其使用一种对客户端透明的方式来动态的扩展对象的功能,同时它也是继承关系的一种替代方案之一,但比继承更加灵活.在现实生活中也可以看到很多装饰者模式的例子,或者可以大胆的说装饰者模式无处不在,就拿一件东西来说,可以给它披上无数层不一样的外壳,但是这件东西还是这件东西,外壳不过是用来扩展这个东西的功能而已,这就是装饰者模式,装饰者的这个角色也许各不相同但是被装饰的对