http://www.devdiv.com/forum.php?mod=viewthread&tid=130200

一、SoundPool类简介与适用场合

1)SoundPool简介

SoundPool类是Android用于管理和播放应用程序的音频资源的类。一个SoundPool对象可以看作是一个可以从APK中导入资源或者从文件系统中载入文件的样本集合。它利用MediaPlayer服务为音频解码为一个原始16位PCM流。这个特性使得应用程序可以进行流压缩,而无须忍受在播放音频时解压所带来的CPU负载和时延。

此外对于低延迟播放,SoundPool还可以管理多个音频流。当SoundPool对象构造时,maxStreams参数的设置表示的是在单一的SoundPool中,同一时间所能播放流的最大数量。利用SoundPool可以跟踪活跃的流的数量。如果其数量超过流的最大数目,SoundPool会基于优先级自动停止先前播放的流。限制流的最大数目,有助于减轻CPU的负荷,减少音频混合对视觉和UI性能的影响。

声音可以通过设置一个非零的循环价值循环。如果值为-1将导致声音永远循环。在这种情况下,应用程序必须明确地调用stop()函数,以停止声音。其他非零值将导致声音按指定数量的时间重复。

在SoundPool中,播放速率也可以改变。1.0的播放率可以使声音按照其原始频率(如果必要的话,将重新采样硬件输出频率)。而2.0的播放速率,可以使声音按照其原始频率的两倍播放。如果为0.5的播放率,则播放速率是原始频率的一半。播放速率的取值范围是0.5至2.0。

优先级的运行从低到高排列的。当用户调用play()函数时,如果活跃的流数目大于规定的maxStreams参数,流分配器将会结束优先级最低的流。如果有多条流都处于最低优先级,优先级系统将会选择关闭最老的流。

一旦声音被成功加载和播放,应用程序可以调用SoundPool.play()来触发的声音。播放过程中的流可又被暂停或继续播放。应用程序还可以通过调整播放率改变音高。

注意,由于资源的限制,流可以被停止,streamID是一个对特定流实例的引用。如果流被停止并且允许更高优先级的流播放,流就不再有效了。然而,应用程序允许调用没有错误的streamID方法。因为如果应用程序不需要关心流的生命周期,这可能有助于简化程序逻辑。

2)适用场合

SoundPool在载入声音文件过程中,使用了单独的线程,不会对视觉和UI性能产生影响。但是由于SoundPool对载入声音文件大小有所限制,这就导致了如果SoundPool没有载入完成,而不能安全调用play方法。好在Android SDK提供了一个SoundPool.OnLoadCompleteListener类来帮助我们了解声音文件是否载入完成,用户只须重载 onLoadComplete(SoundPool soundPool, int sampleId, int status) 方法即可实现。

与MediaPlayer相比,MediaPlayer存在着资源占用量较高、延迟时间较长、不支持多个音频同时播放等缺点,但SoundPool本身由于内存资源申请有严格限制,所以在开发过程中,笔者建议尽量用SoundPool来播放一些较短的声音片段或者音效。  

二、使用SoundPool播放声音

1)SoundPool对象初始化

我们可以调用SoundPool的构造函数public SoundPool (int maxStreams, int streamType, int srcQuality)来初始化SoundPool对象。

其中参数说明如下:

maxStreams:指定支持多少个声音,SoundPool对象中允许同时存在的最大流的数量。
        streamType:制定声音类型,流类型可以分为STREAM_VOICE_CALL, STREAM_SYSTEM, STREAM_RING,STREAM_MUSIC 和 STREAM_ALARM四种类型。在AudioManager中定义。
        srcQuality:指定声音品质(采样率变换质量)。目前没有用到,可以设为0。

2)载入声音资源

调用load方法载入声音资源,SoundPool提供了4个Load方法,比较常用的是以下两个:

Public int load(Context context, int resId, int priority):从resId所对应的资源加载声音。
        Public int load(String path, int priority):从path对应的文件中加载声音。

上面两个方法中都有一个priority参数,该参数目前还没有任何作用,Android建议将该参数设置为1,保持和未来的兼容性。

同时,这两个方法加载声音之后,都会返回该声音的ID,以后程序就可以通过该声音的ID来播放指定声音。

3)播放控制

要播放SoundPool中的声音,须调用int play (int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate)方法。

其中参数说明如下:

soundID:Load()函数返回的声音ID号。
        leftVolume:左声道音量设置。
        rightVolume:右声道音量设置。
        priority:指定播放声音的优先级,数值越高,优先级越大。
        loop:指定是否循环。-1表示无限循环,0表示不循环,其他值表示要重复播放的次数。
        rate:指定播放速率。1.0的播放率可以使声音按照其原始频率。而2.0的播放速率,可以使声音按照其原始频率的两倍播放。如果为0.5的播放率,则播放速率是原始频率的一半。播放速率的取值范围是0.5至2.0。

4)释放资源

播放结束,我们可以调用release()方法释放所有SoundPool对象占据的内存和资源。

5)实例分析

下面通过一个简单的Demo来分析一下SoundPool的用法,布局文件非常简单,不再给出代码。

MainActivity.java的内容如下:

view source print?
01 package com.devdiv.test.soundpool_test;
02  
03 import java.util.HashMap;
04  
05 import android.app.Activity;
06 import android.media.AudioManager;
07 import android.media.SoundPool;
08 import android.os.Bundle;
09 import android.view.View;
10 import android.view.View.OnClickListener;
11 import android.widget.Button;
12  
13 public class MainActivity extends Activity implements OnClickListener {
14        
15         Button bombButton;
16         Button shotButton;
17         Button arrowButton;
18         Button allButton;
19        
20         SoundPool mSoundPool = null;
21        
22         HashMap<Integer, Integer> soundMap = new HashMap<Integer, Integer>();
23  
24     @Override
25     public void onCreate(Bundle savedInstanceState) {
26         super.onCreate(savedInstanceState);
27         setContentView(R.layout.activity_main);
28        
29         bombButton = (Button) findViewById(R.id.bomb);
30         shotButton = (Button) findViewById(R.id.shot);
31         arrowButton = (Button) findViewById(R.id.arrow);
32         allButton = (Button) findViewById(R.id.all);
33        
34                 //设置最多可容纳10个音频流,音频的品质为5
35         mSoundPool = new SoundPool(10, AudioManager.STREAM_SYSTEM, 5);
36                 //load方法加载指定音频文件,并返回所加载的音频ID。此处使用HashMap来管理这些音频流
37                 soundMap.put(1 , mSoundPool.load(this, R.raw.bomb , 1));
38                 soundMap.put(2 , mSoundPool.load(this, R.raw.shot , 1));
39                 soundMap.put(3 , mSoundPool.load(this, R.raw.arrow , 1));
40                
41                 bombButton.setOnClickListener(this);
42                 shotButton.setOnClickListener(this);
43                 arrowButton.setOnClickListener(this);
44                 allButton.setOnClickListener(this);
45     }
46    
47         //重写OnClickListener监听器接口的方法
48         @Override
49         public void onClick(View v) {
50                 // TODO Auto-generated method stub
51                 //判断哪个按钮被单击
52                 switch (v.getId()) {
53                 case R.id.bomb:
54                         mSoundPool.play(soundMap.get(1), 1, 1, 0, 0, 1);
55                         break;
56                 case R.id.shot:
57                         mSoundPool.play(soundMap.get(2), 1, 1, 0, 0, 1);
58                         break;
59                 case R.id.arrow:
60                         mSoundPool.play(soundMap.get(3), 1, 1, 0, 0, 1);
61                         break;
62                 case R.id.all:
63                         mSoundPool.play(soundMap.get(1), 1, 1, 0, 0, 1);
64                         mSoundPool.play(soundMap.get(2), 1, 1, 0, 0, 1);
65                         mSoundPool.play(soundMap.get(3), 1, 1, 0, 0, 1);
66                 default:
67                         break;
68                 }
69         }
70  
71 }

通常,为了更好地管理SoundPool所加载的每个声音的ID,程序一般会使用一个HashMap<Integer,Integer>对象来管理声音。按照上面的步骤初始化,载入声音,并且把按钮绑定监听器,点击按钮播放相应声音。

SoundPool类简介与适用场合相关推荐

  1. DriverManager 驱动管理器类简介 JDBC简介(三)

    驱动程序管理器是负责管理驱动程序的,驱动注册以后,会保存在DriverManager中的已注册列表中 后续的处理就可以对这个列表进行操作 简言之,驱动管理器,就是字面含义,主要负责就是管理 驱动 概述 ...

  2. 【Groovy】集合遍历 ( 使用集合的 reverseEach 方法进行遍历 | 倒序集合迭代器 ReverseListIterator 类简介 | 代码示例 )

    文章目录 一.使用集合的 reverseEach 方法进行倒序遍历 二.倒序集合迭代器 ReverseListIterator 类简介 三.代码示例 一.使用集合的 reverseEach 方法进行倒 ...

  3. Application 类 简介

    2019独角兽企业重金招聘Python工程师标准>>> Application 类 简介 每次程序运行时,程序的Application 类都是保持实例化.与Activity不同:配置 ...

  4. java.util.Stack类简介

    转载自  java.util.Stack类简介 Stack是一个后进先出(last in first out,LIFO)的堆栈,在Vector类的基础上扩展5个方法而来 Deque(双端队列)比起St ...

  5. Minify框架分析,主要功能类简介

    主要功能类简介 config.php      默认缩小应用程序的配置 index.php:为实施默认缩小的前端控制器请勿编辑!通过config.php和groupsConfig.php配置实用程序 ...

  6. 03MFC的ODBC类简介

    MFC的ODBC类简介 MFC的ODBC类对较复杂的ODBC API进行了封装,提供了简化的调用接口,从而大大方便了数据库应用程序的开发.程序员不必了解ODBC API和SQL的具体细节,利用ODBC ...

  7. php 什么是对象,什么是PHP类和类的对象(PHP的类简介)

    什么是PHP类和类的对象(PHP的类简介) 类(Class):是一些变量与一些使用这些变量的函数的集合. 可简单理解为函数和变量的集合,或变量和函数的定义的集合. 语法是: class Class_n ...

  8. CMarkup类简介

    CMarkup类简介 Initialization Load: Populates the CMarkup objectfrom a file and parses it. SetDoc: Popul ...

  9. 【Android进阶】20、音频播放:SoundPool 类、单元测试:Espresso框架

    文章目录 20.1 创建 SoundPool 20.2 访问 assets 20.3 加载音频文件 20.4 播放音频 20.5 单元测试 20.6 创建测试类 20.7 配置测试类 20.8 编写测 ...

最新文章

  1. HUB管理步骤、桥端设置步骤和客户端使用步骤
  2. 2021.01.30 Visual QA论文阅读
  3. Bzoj 3652: 大新闻(数位dp)
  4. 调整Redmine的用户显示格式
  5. 在Docker上运行微服务
  6. python通过pop3方式登录邮箱(qq,新浪,网易)
  7. mac定时备份mysql_定时备份mysql数据库
  8. 企业微信机器人消息发送(文本、图片、文件)
  9. 多个excel工作簿合并_EXCEL多表、多工作簿合并拆分,随心所欲(完善版)
  10. osgEarth的Rex引擎原理分析(一一四)rex与mp引擎的关系
  11. Mac上使用LaTeX(小白入门配置Latex)
  12. Java软件测试工程师之学习进阶路线
  13. ESP32-C3入门教程 WiFi篇②——WiFi Station 模式连接到 AP 热点接入点
  14. 10 圆柱的表面积(六下)
  15. 【实验1 顺序结构】7-3 sdut-C语言实验-虎子分糖果
  16. 基于SpringBoot 2.x开发的简易版图书管理系统(实现对图书的CRUD)
  17. django-cas
  18. python基于PHP+MySQL的家装设计平台管理系统
  19. logback异常RuntimeException in Action for tag [encoder] java.lang.NumberFormatException
  20. arcgis sde mysql_ArcGis中地理数据库(sde)中概念及常见函数

热门文章

  1. 由GPS定位的经纬度转换成百度地图经纬度坐标
  2. 【ROS】Ubuntu18.04 + ROS操作系统安装
  3. SDUT OJ单个字符输入和输出(顺序结构)
  4. 软件质量管理-1-课程介绍
  5. ubuntu源换成清华源_Ubuntu18.04更换软件包源(清华源)
  6. 杰理AD14N/AD15N---GPIO唤醒引脚触摸时会有效的问题
  7. BioID人脸数据库简介
  8. STM32CubeMX生成STM32F072 USB 自定义HID Device
  9. 控制算法-模型预测MPC
  10. 另类弹窗十倍放大流量