《Android编程权威指南》之音频播放与单元测试(二)

本文介绍了《Android编程权威指南》中关于音频播放、单元测试以及Jetpack Compose的使用。讲解了如何编写测试函数、使用Mockito进行模拟对象测试,以及在应用中实现音频释放。同时,探讨了整合测试和模拟对象在测试中的作用,并给出设备旋转和播放进度控制的挑战练习。最后提到了Jetpack Compose的优势和学习建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

《Android编程权威指南》第 20 章第二篇,补充完 BeatBox 应用的单元测试啦。

八、编写测试函数

测试函数将用到 @Test 注解。

 @Test
    fun exposesSoundNameAsTitle(){
        assertThat(subject.title,`is`(sound.name))
    } 

assertThat(…) 选 org.junit 库里的 Assert.assertThat(…) 函数,is(…) 选 org.hamcrest 库里的 Is.is 函数。

上面代码意思是断定测试对象获取标题函数和 sound 的获取文件名函数返回相同的值。如果不同,单元测试失败。

接下来测试 SoundViewModel 和 BeatBox.play(Sound) 的交互。

 @Test
    fun callsBeatBoxPlayOnButtonClicked(){
        subject.onButtonClicked()
    } 

为了测试 SoundViewModel 不让它跟 BeatBox 绑太死,不依赖 BeatBox 对象,就在此测试案例中模拟出 BeatBox 对象。

class SoundViewModelTest {
    ...
    private lateinit var beatBox: BeatBox
    @Before
    fun setUp() {
        beatBox = mock(BeatBox::class.java)
        ...
    }
    ...
} 

Mockito 的 verify(Object) 可以确认,要测试的函数是否都按预期被调用了。

 @Test
    fun callsBeatBoxPlayOnButtonClicked(){
        ...
        verify(beatBox).play(sound)
    } 

失败了

然后按照书中过程补充修正一下,把 BeatBox 传给 SoundViewModel,修正 SoundHolder 中的错误,在测试类里提供模拟板 BeatBox,实现 onButtonClicked() 函数。具体代码略了,见 Demo。

通过了

九、数据绑定回调

在布局文件里,添加数据绑定 lambda 表达式,让按钮对象和 SoundViewModel.onButtonClicked() 函数关联起来。

 <Button
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:onClick="@{()->viewModel.onButtonClicked()}"
        android:text="@{viewModel.title}"
        tools:text="Sound name" /> 

运行应用,点击按钮,就能听到奇怪的喊叫声了,可以自行体验下。

十、释放音频

音频播放完毕,应调用 SoundPool.release() 函数释放 SoundPool。

在 BeatBox 中添加方法:

 fun release(){
        soundPool.release()
    } 

然后在 MainActivity 销毁的时候调用它:

 override fun onDestroy() {
        super.onDestroy()
        beatBox.release()
    } 

十一、深入学习:整合测试

  • 单元测试中,受测对象是单个类。保证各个类单元正确运行,相互之间的交互符合预期。

  • 整合测试中,受测对象是应用的一部分,包括协同工作的众多对象。验证受测各部分已正确整合在一起,按预期发挥作用。在 Android 平台上,整合测试通常还是指 UI 级别的测试(和UI部件交互,验证它们的行为表现是否符合预期)。常以 instrumentation 测试来实施。

Espresso 是 Google 开发的一个 UI 测试框架,可用来测试 Android 应用。通常新项目都会自动的引用这个依赖。

 androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' 

可用它来测试某个 activity 的行为。

断定屏幕上某个视图显示了第一个 sample_sounds 受测文件的文件名:

@RunWith(AndroidJUnit4::class)
class MainActivityTest {
    
    @get:Rule
    val activityRule = ActivityTestRule(MainActivity::class.java)
    
    @Test
    fun showsFirstFileName(){
        onView(withText("65_cjipie"))
            .check(matches(isDisplayed()))
    }
} 

@RunWith(AndroidJUnit4.class) 表明,这是一个Android工具测试,需要 activity 和其他 Android 运行时环境支持。

activityRule 上的 @get:Rule 注解告诉 JUnit,运行测试前,要启动一个 MainActivity 实例。

onView(withText(“65_cjipie”)) 会找到显示 “65_cjipie” 的视图,对其执行测试。

check(matches(isDisplayed())) 用来判定视图在屏幕上看得见。

有关 Espresso 详情参考:

developer.android.com/training/te…

十二、深入学习:模拟对象与测试

模拟对象假扮成其他不相干的组件,为的就是隔离受测对象。对于单元测试来说,能快速创建模拟对象的 Mockito 非常有用。

但是整合测试时,最好避免使用像 Mockito 这样的自动模拟测试框架,因为模拟太重了,需要很多整合测试共享,太繁琐。

**基本原则:**模拟对象的效用不应超出受测组件的边界。应着重关注测试范围,防止测试越界。

十三、挑战练习:播放进度控制

给 BeatBox 应用添加播放进度控制功能,在MainActivity中,使用SeekBar部件控制SoundPool的play(Int, Float, Float, Int, Int, Float)函数的播放速率参数值。

参考 Demo,指不定啥时候就更新了。O(∩_∩)O哈哈~

十四、挑战练习:设备旋转问题

给 BeatBox 应用添加一个 Jetpack 版 ViewModel,实现在设备旋转时保存BeatBox对象。

参考 Demo,指不定啥时候就更新了。O(∩_∩)O哈哈~

其他

BeatBox 项目 Demo 地址:

github.com/visiongem/A…


🌈关注我吖~❤️

公众号:妮K妮K妮

A%2F%2Fgithub.com%2Fvisiongem%2FAndroidGuideApp%2Ftree%2Fmaster%2FBeatBox “https://github.com/visiongem/AndroidGuideApp/tree/master/BeatBox”)


🌈关注我吖~❤️

公众号:妮K妮K妮

最后

有小伙伴私信问Compose的问题,好不好用啊,现在要不要学啊?

其实答案很简单,自从谷歌2019年公布了声明式UI框架Jetpack Compose后,两年多的时间,各种大力宣传,和大量资源的倾斜,API功能都趋于稳定了。

至于好不好用,各种用过的同行都是持肯定态度的。优势大概就是这四点:

强大的工具和直观的Kotlin API
简化并加速了Android上的UI开发
可以帮助开发者用更少更直观的代码创建View
有更强大的功能,以及还能提高开发速度

这么大的优势,毋庸置疑,肯定是要学的嘛,而且越快掌握越好。别等刀架到脖子上了,才去练金钟罩。

至于怎么快速上手,可以给大家免费分享一份**《Jetpack Compose 完全开发手册》**,手把手教大家从入门到精通。

第一章 初识 Jetpack Compose

  • 为什么我们需要一个新的UI 工具?

  • Jetpack Compose的着重点

    加速开发
    强大的UI工具
    直观的Kotlin API

图片

  • API 设计

图片

  • Compose API 的原则
    一切都是函数
    顶层函数(Top-level function)
    组合优于继承
    信任单一来源

图片

  • 深入了解Compose
    Core
    Foundation
    Material

图片

  • 插槽API

第二章 Jetpack Compose构建Android UI

  • Android Jetpack Compose 最全上手指南
    Jetpack Compose 环境准备和Hello World
    布局
    使用Material design 设计
    Compose 布局实时预览
    ……

图片

  • 深入详解 Jetpack Compose | 优化 UI 构建
    Compose 所解决的问题
    Composable 函数剖析
    声明式 UI
    组合 vs 继承
    封装
    重组
    ……

图片

  • 深入详解 Jetpack Compose | 实现原理
    @Composable 注解意味着什么?
    执行模式
    Positional Memoization (位置记忆化)
    存储参数
    重组
    ……

图片

第三章 Jetpack Compose 项目实战演练(附Demo)

  • Jetpack Compose应用1
    开始前的准备
    创建DEMO
    遇到的问题

图片

  • Jetpack Compose应用2
  • Jetpack Compose应用做一个倒计时器
    数据结构
    倒计时功能
    状态模式
    Compose 布局
    绘制时钟

图片

  • 用Jetpack Compose写一个玩安卓App
    准备工作
    引入依赖
    新建 Activity
    创建 Compose
    PlayTheme
    画页面
    底部导航栏
    管理状态
    添加页面

图片

  • 用Compose Android 写一个天气应用
    开篇
    画页面
    画背景
    画内容
    ……

图片

  • 用Compose快速打造一个“电影App”
    成品
    实现方案
    实战
    不足
    ……

图片

由于篇幅限制,文档的详解资料太全面,细节内容太多,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
有需要的话可以点下面二维码免费领取↓↓↓

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值