1.Android-Native开发系列之利用AAudio播放音频
2.安卓系统目前最高的版本是多少
3.android.bp
4.JobIntentService源码解析
Android-Native开发系列之利用AAudio播放音频
前言 在Android C/C++层实现音频播放/录制功能,大家可能首先想到的是利用opensles。这是经过考验的实现方式,适配广泛。然而,若项目最低版本支持Android 及以上,商城网站源码在哪追求最小延迟与最高性能时,可考虑AAudio。 博主之前使用opensles处理音频,后尝试oboe、aaudio实现,有感而发,特此记录,双向马丁源码以供参考。什么是AAudio?
AAudio是Android 8.0引入的一种新型C风格接口的底层音频库,旨在追求性能与低延迟。它专注于原始数据的播放与录制,如播放PCM数据。与opensles不同,AAudio不包含编解码模块。 oboe是对opensles与aaudio的封装,它根据设备判断选择使用aaudio或opensles。例如,在低于Android 8.0的设备上,它会使用opensles。黑马 mybatis 源码配置AAudio开发环境与AAudioStream
AAudioStream是关键概念,它是与AAudio交换音频数据的基础。我们首先创建AAudioStreamBuilder,然后通过它配置AAudioStream。创建AAudioStreamBuilder
AAudioStream的创建采用builder模式,故需先创建对应的builder对象。配置AAudioStream
通过builder的setXXX函数配置AAudioStream。简要概述这些函数,具体详情请参阅源码注释。 注释的回调用于后续使用,暂不展开。创建AAudioStream
调用openStream获取配置的源码 小学题库AAudioStream对象。接下来,可利用AAudioStream处理音频数据,通过调用相关getXXX函数,验证配置是否满足预期。操作AAudioStream
AAudioStream的状态转换流程图展示了状态变化的路径。涉及的函数包括请求状态变更的函数,这些函数为异步调用。
AAudioStream处理音频数据有直接读写与回调两种方式,具体选择取决于项目需求。通过callback回调处理数据
回调方式推荐,因其能提供更好的性能。直接读写数据到流方式在大多数情况下的小说生成源码延迟指标表现良好,具体取决于项目需求。 使用callback方式处理数据需设置回调函数dataCallback与errorCallback,分别在AAudio需要数据时与出现错误时触发。注意
回调函数内避免执行耗时任务。errorCallback触发时需在新线程中处理,可直接调用AAudioStream相关的getXXX函数。AAudio使用demo
GitHub上已提供使用demo,欢迎查看并star。补充内容
underrun & overrun
underrun与overrun是音频数据生产和消费节奏不匹配导致的问题,分别指播放时未及时写入数据与录制时未及时读取数据。 AAudio通过动态调整缓冲区大小来降低延迟,避免underrun。Thread safety
AAudio接口并非完全线程安全,使用时需注意。结论
AAudio接口简洁,与opensles相比代码量减少,功能略显不足,如解码与音量控制等。选择取决于实际需求。 已提供GitHub链接,配合文章阅读更易理解。 参考链接:developer.android.com/ndk/guides/...安卓系统目前最高的版本是多少
当前,安卓系统已经步入了其最先进版本的行列,即Android 8.0。作为一款起源于Linux的开放源代码操作系统,安卓因其灵活性和广泛的应用范围而在移动设备市场占据主导,特别是智能手机和平板电脑。由Google和开放手机联盟携手打造,安卓以其独特的四大组件构建了其功能基础:活动组件负责呈现各类应用程序的功能,服务组件则在后台默默运行,无需用户界面的直接交互;广播接收器组件则扮演着接收和处理各种系统消息的角色,而内容提供器组件则充当了不同应用程序间数据共享的桥梁,确保信息的高效流通。
android.bp
å¼ç¨åæ
æ©æçAndroidç³»ç»é½æ¯éç¨Android.mkçé ç½®æ¥ç¼è¯æºç ï¼ä»Android 7.0å¼å§å¼å ¥Android.bpã
Android 7.0å¼å ¥ninjaåkati
Android 8.0使ç¨Android.bpæ¥æ¿æ¢Android.mkï¼å¼å ¥Soong
Android 9.0强å¶ä½¿ç¨Android.bp
1.1 模å
å®ä¹ä¸ä¸ªæ¨¡åä»æ¨¡åçç±»åå¼å§ï¼æ¨¡åæä¸åçç±»åï¼å¦åé¢ä¾åä¸çcc_library_sharedï¼å½ç¶ç±»åè¿æå¾å¤ç§ï¼è¬å¦cc_binary android_app cc_library_staticççã模åå å«ä¸äºå±æ§æ ¼å¼ä¸ºâproperty-name:property-valueâï¼å ¶ä¸nameå±æ§å¿ é¡»æå®ï¼å ¶å±æ§å¼å¿ é¡»æ¯å ¨å±å¯ä¸çã
srcs å±æ§ä»¥å符串å表çå½¢å¼æå®ç¨äºç¼è¯æ¨¡åçæºæ件ãæ¨å¯ä»¥ä½¿ç¨æ¨¡åå¼ç¨è¯æ³ â:â æ¥å¼ç¨çææºæ件çå ¶ä»æ¨¡åçè¾åºï¼å¦ genrule æ filegroupã
1.2 åé
åéèå´éå®ä¸ºå£°æå®ä»¬çæ件çå ¶ä½é¨åï¼å¯ä»¥ä½¿ç¨ â=â å·èµå¼ï¼ ä½æ¯ä¸è½ä½¿ç¨ âï¼=â èµå¼ãåéæ¯ä¸å¯åçï¼ä½æä¸ä¸ªä¾å¤å®ä»¬å¯ä»¥éä¸+= èµå¼ï¼ä½ä» å¨åé被å¼ç¨ä¹åã
1.3 注é
Android.bp使ç¨åè¡æ³¨é//åå¤è¡æ³¨é/* */两ç§æ¹å¼ã
1.4ç±»å
å ·ä½æ¯æ以ä¸å ç§ç±»åï¼
1.5 æä½ç¬¦
Stringç±»åãå符串å表类ååMapç±»åæ¯ææä½ç¬¦â+âã
1.6 æ¯æ模åç±»å
Android.bpå¯ä»¥æ¯æandroid_appãcc_binaryãcc_binary_hostçå¤ç§ç±»åï¼å ·ä½å®ä¹å¨Androidæºç çbuild/soong/androidmk/cmd/androidmk/android.go
1.7 æ¯æé¢ç¼è¯ç±»å
1.8 æ¡ä»¶å¼ç¼è¯
JobIntentService源码解析
Android 8.0引入了更严格的系统资源管控,包括后台限制规则。
在Android 8.0中,禁止应用在后台运行时创建Service。
若应用在后台运行,将会收到错误提示。
JobIntentService是Android 8.0中新增的类,继承自Service。
该类用于执行加入队列的任务。对于Android 8.0及以上系统,JobIntentService任务将通过JobScheduler.enqueue执行,而8.0以下系统则继续使用Context.startService。
JobIntentService使用便捷,只需调用YourService.enqueueWork(context, new Intent())方法。
相较于JobService,JobIntentService简化了操作,开发者无需关注其生命周期,避免了在后台运行时创建Service导致的crash问题,且通过静态方法即可启动。
源码解析如下:首先记录几个关键变量的含义。
在Android 8.0以上的系统中,执行流程如下。
work的具体逻辑处理在何处?
通过JobService的工作原理,查找onStartJob方法。
最终,处理work的逻辑会流转至AsyncTask中,通过protected abstract void onHandleWork(@NonNull Intent intent)方法实现。
子类需实现jobIntentService处理work,使用线程池的AsyncTask执行,无需考虑主线程阻塞问题。
针对Android 8.0以下系统,流程如下:回到onStartCommand方法。
同样,最终会流转至Asynctask任务执行onHandleWork。