Android C++系列:通过 JNI 访问 Java 字段和方法调用

2024-06-30
阅读 5 分钟
630
在前面的两篇文章中,介绍了 Android 通过 JNI 进行基础类型、字符串和数组的相关操作,并描述了 Java 和 Native 在类型和签名之间的转换关系。
封面图

Android C++系列:访问Assets 文件夹

2024-06-29
阅读 4 分钟
687
assets目录是Android的一种特殊目录,用于放置APP所需的固定文件,且该文件被打包到APK中时,不会被编码到二进制文件。 Android还存在一种放置在res下的raw目录,该目录与assets目录不同。 区别点:
封面图

Android C++系列:认识JNI

2024-06-29
阅读 2 分钟
438
JNI不仅仅是Android特有的,它是属于Java平台的,它允许在Java虚拟机内运行的java代码与其他编程语言(如c, c++和汇编语言)编写的程序和库进行交互。Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI一开始是为了本地已编译语言,尤其是C和C++而设计的,但是并不是说不能使用...
封面图

Tensorflow Lite移动平台编译

2024-06-28
阅读 5 分钟
671
如果不做定制化操作,我们不需要自己编译TensorFlow Lite Android库。我们可以直接使用位于MavenCentral的TensorFlow Lite AAR。但是在某些情况下,我们需要本地编译TensorFlow Lite。例如,您可能正在构建一个包含operations selected from TensorFlow的自定义二进制文件,或者需要对TensorFlow Lite进行局部修改。

【Android 构建新工具】Bazel 构建Android项目

2024-06-28
阅读 6 分钟
681
【Android 构建新工具】Bazel 构建Android项目本文我们使用Bazel构建一个最简单的Android项目。Bazel提供了编译Android程序内置的方法,具体参考:Android Rules1. 环境准备Bazel只是编译工具,不是真正的编译器,所以还是需要Andorid开发的SD、NDK以及Android Studio,并配置开发环境。接下来就是安装Bazel。由于平时在...
封面图

Bazel与Gradle工具差异

2024-06-27
阅读 6 分钟
560
Bazel和Gradle强调构建体验的不同方面。在某种程度上,它们的侧重点是互斥的——Gradle对灵活性和非突出性的要求对它的构建结构进行了限制,而Bazel对可靠性和性能的要求产生了强制不可协商的限制。
封面图

Bazel构建工具介绍

2024-06-27
阅读 2 分钟
476
Android开发我们主要用到的编译器是Java的Java编译器以及C/C++的gcc/clang编译器。对应Java层构建工具最初是Ant,后面Maven以及gradle;C/C++构建工具主要是make/cmake,做过系统开发或者chromeium,可能还用过ninjia、gclient、mm等。最近在编译Android平台的tensorflow lite库,发现官方使用的是Bazel构建工具,大概了...
封面图

Android C++系列:vector最佳实践

2024-06-26
阅读 2 分钟
553
Java中常见的集合有List、Set、Map等,并且这些都是支持泛型的。类似的C++中也提供了vector容器,并且vector是模板类(类似Java的泛型)。使用vector要用到的头文件:
封面图

Android C++系列:string最佳实践二

2024-06-26
阅读 1 分钟
897
这里涉及指针指向常量字符串时和使用常量内存初始化数组的区别。为了节省内存,C/C++把常量字符串放到单独的一个内存区域。当几个指针赋值给相同的常量字符串时,它们实际上会指向相同的内存地址。而用常量内存初始化数组,则会把常量字符串内容拷贝到数组开辟的内存。
封面图

Android C++系列:string最佳实践一

2024-06-25
阅读 3 分钟
774
字符串拼接直接用+号既可,字符串比较实用equel方法,同时还提供了StringBuilder和StringBuffer可变的字符串。它们继承了同一个抽象的字符串父类:AbstractStringBuilder。

Android C++系列:JNI中发送Http网络请求

2024-06-25
阅读 10 分钟
895
libcurl是一个免费和易于使用的客户端URL传输库,支持DICT, FILE, FTP, FTPS, GOPHER, gopers, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, POP3, POP3S, RTMP, RTMP, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET和TFTP。libcurl支持SSL证书,HTTP POST, HTTP PUT, FTP上传,HTTP表单上传,代理,HTTP/2, HTTP/...
封面图

Android C++系列:C++最佳实践5const

2024-06-24
阅读 3 分钟
526
在Java中我们定义常量通常用final static TYPE variableName = xxx来实现,在C语言中我们通常用预编译宏来实现:#define MAX 100,在C++中虽然我们仍可以使用预编译宏,但是已经不推荐这么干了。在Effective c++ 的条款1中:提到“尽量用编译器而不用预处理”,因为#define经常被认为好象不是语言本身的一部分。而且有时候...
封面图

Android C++系列:C++最佳实践4多重继承与虚继承

2024-06-23
阅读 3 分钟
519
Java和C++在语法层面比较的时候就不得不提到C++的多继承,我们知道Android是单继承,C++是多继承。在大型项目中不可避免的会用到多继承,本文分析C++多继承的一些特征。
封面图

Android C++系列:C++最佳实践3继承与访问控制

2024-06-23
阅读 3 分钟
649
整个结构还是比较简单的,从类内部到本包到子类到外部包权限越来越小,比较好理解也比较好记忆。但是在C++中访问控制要复杂很多,因为不仅有属性和方法的访问控制,还有继承时的派生列表访问说明符。今天我们着重了解访问控制。
封面图

Android C++系列:C++最佳实践2抽象类

2024-06-22
阅读 1 分钟
477
OOP面向对象程序设计的核心是数据抽象,继承和动态绑定。前面的文章我们介绍了使用virtual的虚类实现动态绑定的多态,有时候我们在做抽象时,对于抽象的实体不想让被人实例化,虚类没有这个功能,我们Java里面我们有抽象类,有接口来抽象一个实体的行为,而不允许被实例化,C++有没有这样的功能呢?C++怎么实现抽象类呢?
封面图

Android C++系列:C++最佳实践1虚函数

2024-06-22
阅读 2 分钟
462
C++多态的核心技术基础就是虚函数,虚函数允许我们使用同样的基类指针调用同一个方法的不同实现版本。我们Android使用Java开发过程中,方法重写技术自动实现了多态,C++角度可能更繁琐一些,本文从Java程序员思维角度来阐述C++虚函数及开发过程一些准则。
封面图

Android C++系列:C++内存结构

2024-06-21
阅读 11 分钟
545
1. Java内存区域划分在了解C++内存区域划分前,我们先了解下Java内存区域划分。作为Android开发,我们根据《Java虚拟机规范》知道Java虚拟机在执行java程序时,会将自己管理的内存划分为以下五个区域:方法区堆程序计数器虚拟机栈本地方法栈每个区域都有自己的用途,并且创建时间和销毁时间也不一样。1.1 方法区方法区是...

Android C++系列:C++11函数特殊特性

2024-06-21
阅读 3 分钟
456
在Python中函数有默认参数等,在C++11中我们发现C++也支持了默认参数;还有C++特有的内联函数、constexpr函数等知识都有不少细节,本文对这些知识做详细介绍。
封面图

Android C++系列:数组在函数中注意事项

2024-06-20
阅读 2 分钟
784
1. 背景数组作为函数形参传递的是数组首元素的地址本来是很简单的知识点,但是在具体使用中还会有一些坑需要注意。2. 数组做函数形参C++中数组有两个特殊的性质:不允许拷贝数组:我们不能将数组的内容拷贝给其他数组作为初始值,也不能用数组为其他数组赋值,所以我们不能以值传递的方式使用数组参数;使用数组时通常会...
封面图

Android C++系列:内存知识整理

2024-06-20
阅读 30 分钟
714
在嵌入式系统中使用C++的一个常见问题是内存分配,即对new 和 delete 操作符的失控。具有讽刺意味的是,问题的根源却是C++对内存的管理非常的容易而且安全。具体地说,当一个对象被消除时,它的析构函数能够安全的释放所分配的内存。这当然是个好事情,但是这种使用的简单性使得程序员们过度使用new 和 delete,而不注意...
封面图

Android C++系列:函数知识知多少

2024-06-19
阅读 1 分钟
529
1. 背景函数可以理解为功能的封装,很基础的功能单元,但是因为它虽然看似简单,但是里面涉及了不少知识点和技巧,我们花一篇文章来整理。2. 函数定义函数有以下几部分定义:返回类型函数名称形参列表函数体函数调用的形式是函数名(),函数调用过程涉及到控制权转移。函数体其实是一个语句块,语句块会涉及到作用域的问题...
封面图

Mp3文件结构全解析(一)

2024-06-18
阅读 13 分钟
879
MP3 文件是由帧(frame)构成的,帧是MP3 文件最小的组成单位。MP3的全称应为MPEG1 Layer-3 音频文件,MPEG(Moving Picture Experts Group) 在汉语中译为活动图像专家组,特指活动影音压缩标准,MPEG 音频文件是MPEG1 标准中的声音部分,也叫MPEG 音频层,它根据压缩质量和编码复杂程度划分为三层,即Layer-1、Layer2、Lay...
封面图

谷歌基于信号特征的语音编码器Lyra Android实践

2024-06-17
阅读 10 分钟
838
通过语音和视频通话与他人在线联系正日益成为日常生活的一部分。实时通信框架,如WebRTC,使这成为可能,依赖于有效的压缩技术,编解码器,编码(或解码)信号传输或存储。几十年来,编解码器一直是媒体应用的重要组成部分,它使需要带宽的应用程序能够有效地传输数据,并使人们期望在任何时间、任何地点都能实现高质量的...
封面图

高级视频编码器性能对比(H265、VP9、AV1)

2024-06-17
阅读 3 分钟
2.2k
目前在视频编解码器中,H264已经成为绝对的主流,被大部分设备、浏览器所支持。虽然有更先进的编码器推出,但是受限于推广速度和设备支持成本,一直未能成为主流。
封面图

Opus从入门到精通(十一)webrtc中opus的使用

2024-06-16
阅读 2 分钟
1k
WebRTC中默认是采用Opus编码,Opus编码是由silk编码和celt编码合并在一起,silk编码是由skype公司开源的一种语音编码,特别适合人声,适合于Voip语音通信。celt和mp3,aac类似,适合于传输音乐。
封面图

Opus从入门到精通(八)Opus编码基础之压缩编码

2024-06-16
阅读 6 分钟
1k
只有在保持信号质量的前提下,设法降低码率及数据量,才能使标准得到应用。而这种降低码率的过程,被称为压缩编码或新源编码.这节介绍一些基础的压缩编码思想与方法,为后面Opus语音编码做基础准备.压缩编码又可以分为无损压缩,有损压损,混合压缩无损压缩编码有:
封面图

Opus从入门到精通(七)Opus编码基础之认识声音

2024-06-15
阅读 3 分钟
766
前面我们分析完Opus的编解码api使用,封装原理等,接下来我们准备分析Opus编码原理.Opus编码是一个复杂的工作,我们需要做一些基本铺垫,包括认识声音,压缩编码基础.认识音频有助于我们了解音频特征,不仅对语音有助于我们理解编码技术,同时在语音识别,TTS等场景提供帮助
封面图

Opus从入门到精通(五)OggOpus封装器全解析

2024-06-15
阅读 19 分钟
905
针对上面的问题我们可以自定义一种封装格式,增加类似于WAV的Header,Header中存储元数据,每一帧音频数据前面增加可以标识帧边界的头,但是又会引出其他问题:
封面图

Opus从入门到精通(四)Opus解码程序实现

2024-06-14
阅读 2 分钟
851
由于我们解码后的数据直接写入文件,无法通过vlc等播放器播放,我们通过lame将解码后的数据再编码成mp3,当然,你要乐意也可以直接价格wav头输出成wav.通过采样率,声道数等创建lame编码器:
封面图

Opus从入门到精通(三)手撸一个Opus编码程序

2024-06-14
阅读 18 分钟
1.3k
编码是我们对脉冲编码调制(Pulse Code Modulation,PCM)的数据进行压缩操作,我们通常通过操作系统麦克风API获取PCM数据,或者从存储的现成的文件的PCM数据:
封面图