name
属性没什么好说的,注意全局唯一就好.
[STATIC | SHARED | MODULE]
的话是生成的库的类型,STATIC
的话生成的是静态库,也就是.a
后缀的.我们一般用的都是SHARED
生成动态链接库,也就是.so
后缀的.
- 导入库
// 语法
add_library( <SHARED|STATIC|MODULE|OBJECT|UNKNOWN> IMPORTED
[GLOBAL])
// 导入编译好的ffmpeg样例
add_library( ffmpeg
SHARED
IMPORTED )
// 设置需要导入的ffmpeg位置
set_target_properties( ffmpeg
PROPERTIES IMPORTED_LOCATION
…/…/…/…/libs/armeabi-v7a/libffmpeg.so )
这种方式可以把我们在外部编译好的.so库导进来
还有几种我也没用过了,可以参考官方文档看下add_library
- include_directories 用来导入相关头文件
include_directories(src/main/cpp)
- find_library 用来引入NDK中提供的库. Android NDK 原生 API
find_library(
定义存储NDK库位置的路径变量的名称。
log-lib
指定CMake要查找的NDK库的名称。
log )
- target_link_libraries 将导入的库和自己的原生库关联起来
target_link_libraries(
指定目标库。
native-lib
将目标库链接到NDK中包含的日志库。
${log-lib} )
FFmpeg
FFmpeg
是一套可以用来记录、处理数字音频、视频,并将其转换为流的开源框架,采用LPL或GPL许可证,提供了录制、转换以及流化音视频的完整解决方案。名称中的mpeg来自视频编码标准mpeg
,而前缀FF
是Fast Forward
的首字母缩写.音视频处理的开源库,可以完成绝大多数音视频相关的功能.很多知名软件,开源库都是基于它进行的二次开发,比如bilibi的ijkPlayer
.
编译FFmpeg
FFmpeg
与大部分GNU软件的编译方式类似,都是通过configure
脚本来实现编译前的定制,这种方式允许用户在编译前对软件进行裁剪,同时通过对最终运行到的系统及目标平台的配置来决定对某些模块设定合适的配置.所以这里是通过configure
的方式来生成Makefile
文件,然后使用make
和make install
编译和安装.
- 配置环境
首先我们需要先准备相关的编译环境,这里推荐在linux
下进行编译,配置简单问题少.当然Mac
也行,不推荐Windows
.
- Linux环境(Ubuntu 16.04)
Windows
的话下载个VMware Workstation
,装个ubuntu
还是方便的. - NDK环境 这里使用的是ndk-r17,附上相关下载链接NDK 下载
- 下载FFmpeg源码 FFmpeg下载地址
- 修改configure文件
由于FFmpeg默认生成的库文件格式为libavcodec.so.xx.xx.x。其中的xx就是主副版本号,这种格式在Ubuntu下使用是没有问题的,但是在Android下开发使用,并不把其作为有效的库文件。所以需要修改其他生成的文件名的格式。
通过修改configure文件要实现,打开configure,找到如下内容:
SLIBNAME_WITH_MAJOR=‘
(
S
L
I
B
N
A
M
E
)
.
(SLIBNAME).
(SLIBNAME).(LIBMAJOR)’
LIB_INSTALL_EXTRA_CMD=‘?(RANLIB)“
(
L
I
B
D
I
R
)
/
(LIBDIR)/
(LIBDIR)/(LIBNAME)”’
SLIB_INSTALL_NAME=‘
(
S
L
I
B
N
A
M
E
W
I
T
H
V
E
R
S
I
O
N
)
′
S
L
I
B
I
N
S
T
A
L
L
L
I
N
K
S
=
′
(SLIBNAME_WITH_VERSION)' SLIB_INSTALL_LINKS='
(SLIBNAMEWITHVERSION)′SLIBINSTALLLINKS=′(SLIBNAME_WITH_MAJOR)$(SLIBNAME)’
修改为:
SLIBNAME_WITH_MAJOR=‘
(
S
L
I
B
P
R
E
F
)
(SLIBPREF)
(SLIBPREF)(FULLNAME)-
(
L
I
B
M
A
J
O
R
)
(LIBMAJOR)
(LIBMAJOR)(SLIBSUF)’
LIB_INSTALL_EXTRA_CMD=‘?(RANLIB)“
(
L
I
B
D
I
R
)
/
(LIBDIR)/
(LIBDIR)/(LIBNAME)”’
SLIB_INSTALL_NAME=‘
(
S
L
I
B
N
A
M
E
W
I
T
H
M
A
J
O
R
)
′
S
L
I
B
I
N
S
T
A
L
L
L
I
N
K
S
=
′
(SLIBNAME_WITH_MAJOR)' SLIB_INSTALL_LINKS='
(SLIBNAMEWITHMAJOR)′SLIBINSTALLLINKS=′(SLIBNAME)’
- 编写脚本文件 在
FFmpeg
根目录下创建build.sh
脚本文件,来更方便的配置configure
.如下:
#!/bin/bash
配置NDK路径
NDK=/home/xinyang/develop/android-ndk-r17
指定了交叉编译环境,使其在编译过程中能够引用到 NDK 提供的原生标头和共享库文件
SYSROOT= N D K / p l a t f o r m s / a n d r o i d − 23 / a r c h − a r m / T O O L C H A I N = NDK/platforms/android-23/arch-arm/ TOOLCHAIN= NDK/platforms/android−23/arch−arm/TOOLCHAIN=NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
声明方法
function build_one
{
./configure
–prefix=KaTeX parse error: Expected 'EOF', got '#' at position 15: PREFIX \ #̲ 设置输出路径 --enabl…TOOLCHAIN/bin/arm-linux-androideabi- \ # 指定交叉编译工具链
–target-os=linux \ # 目标系统 android基于linux 所以这里指定为linux
–arch=armeabi-v7a \ # 目标平台架构
–enable-cross-compile # 开启交叉编译
–sysroot=$SYSROOT \ # 交叉编译环境
–extra-cflags=“-Os -fpic
A
D
D
I
C
F
L
A
G
S
"
−
−
e
x
t
r
a
−
l
d
f
l
a
g
s
=
"
ADDI_CFLAGS" \ --extra-ldflags="
ADDICFLAGS" −−extra−ldflags="ADDI_LDFLAGS”
KaTeX parse error: Expected 'EOF', got '}' at position 56: …e make install }̲ CPU=armeabi-v7…(pwd)/android/$CPU
ADDI_CFLAGS=“-marm”
build_one
–cross-prefix
类似于通配符方式指定 bin 目录下以 arm-linux-androideabi- 开头的交叉编译工具,假如不支持这种配置方式则需分别指定:
- CC:$TOOLCHAIN/bin/arm-linux-androideabi-gcc 编译器,对C源文件进行编译处理,生成汇编文件.
- CXX:$TOOLCHAIN/bin/arm-linux-androideabi-g++
- AR:$TOOLCHAIN/bin/arm-linux-androideabi-ar 打包器,用于库操作,可以通过该工具从一个库中删除或者增加目标代码模块.
- LD:$TOOLCHAIN/bin/arm-linux-androideabi-ld 链接器,为前面生成的目标代码分配地址空间,将多个目标文件链接成一个库或是可执行文件.
- 执行脚本 cd 到ffmpeg目录下
chmod 777 build.sh
首先修改下脚本文件的可执行权限
./build.sh
然后执行脚本,整个过程比较慢,耐心等待就好,整个过程大概需要5-10分钟.编译完成后就可以看到如下图,其中include
中是一些头文件,lib
中就是生成的.so动态库了
集成FFmpeg
到这里就可以把生成的.so文件集成到我们的项目中了,来看看步骤:
-
项目关联NDK,按这里的教程执行向您的项目添加C和C++ 代码;
-
拷贝生成的.so文件到
libs
目录下(或是jniLibs); -
拷贝生成的
include
文件夹到cpp
目录; -
拷贝
ffmpeg\fftools
目录下文件到cpp目录; -
编写
native
方法
package com.xinyang.ndkdemo;
public class FFmpegCmd {
static {
System.loadLibrary(“ffmpeg”);
}
public native static void handle();
}
- 在
cpp
目录下创建ffmpeg_cmd.c
文件,实现native
方法,这里可以采用javah
生成头文件再实现的方式,也可以直接在java
类中使用快捷键提示,直接生成方法:
#include <jni.h>
#include <malloc.h>
#include <string.h>
#include <android/log.h>
#include “ffmpeg/ffmpeg.h”
JNIEXPORT void JNICALL Java_com_xinyang_ndkdemo_FFmpegCmd_handle
(JNIEnv *env, jclass obj){
char info[40000] = {0};
av_register_all();
AVCodec *c_temp = av_codec_next(NULL);
while(c_temp != NULL){
if(c_temp->decode!=NULL){
sprintf(info,“%s[Dec]”,info);
}else{
sprintf(info,“%s[Enc]”,info);
}
switch(c_temp->type){
case AVMEDIA_TYPE_VIDEO:
sprintf(info,“%s[Video]”,info);
break;
case AVMEDIA_TYPE_AUDIO:
sprintf(info,“%s[Audio]”,info);
break;
default:
sprintf(info,“%s[Other]”,info);
break;
}
sprintf(info,“%s[%10s]\n”,info,c_temp->name);
c_temp=c_temp->next;
}
__android_log_print(ANDROID_LOG_INFO,“myTag”,“info:\n%s”,info);
}
这段程序用于输出 FFmpeg 支持的编解码信息,通过 < android/log.h > 的 __android_log_print 方法可以直接将信息输出到 Android Studio 的 logcat 。
- 编辑
CMakeLists.txt
导入相关.so文件,使用add_library
导入库的方式把生成的.so文件依次导入,使用include_directories
导入头文件,最后再用target_link_libraries
把导入的库和生成的目标库关联起来,如下所示:
For more information about using CMake with Android Studio, read the
documentation: https://d.android.com/studio/projects/add-native-code.html
Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
Creates and names a library, sets it as either STATIC
or SHARED, and provides the relative paths to its source code.
You can define multiple libraries, and CMake builds them for you.
Gradle automatically packages shared libraries with your APK.
add_library( # Sets the name of the library.
ffmpeg
Sets the library as a shared library.
SHARED
Provides a relative path to your source file(s).
src/main/cpp/ffmpeg_cmd.c
src/main/cpp/ffmpeg/cmdutils.c
src/main/cpp/ffmpeg/ffmpeg.c
src/main/cpp/ffmpeg/ffmpeg_filter.c
src/main/cpp/ffmpeg/ffmpeg_opt.c
)
include_directories(src/main/cpp)
include_directories(src/main/cpp/include)
add_library(
avutil-55
SHARED
IMPORTED
)
set_target_properties( avutil-55
PROPERTIES IMPORTED_LOCATION
…/…/…/…/libs/armeabi-v7a/libavutil-55.so )
add_library(
avcodec-57
SHARED
IMPORTED
)
set_target_properties( avcodec-57
PROPERTIES IMPORTED_LOCATION
…/…/…/…/libs/armeabi-v7a/libavcodec-57.so )
add_library(
avformat-57
SHARED
IMPORTED
)
set_target_properties( avformat-57
PROPERTIES IMPORTED_LOCATION
…/…/…/…/libs/armeabi-v7a/libavformat-57.so )
add_library(
avdevice-57
SHARED
IMPORTED
)
set_target_properties( avdevice-57
PROPERTIES IMPORTED_LOCATION
…/…/…/…/libs/armeabi-v7a/libavdevice-57.so )
add_library(
swresample-2
SHARED
IMPORTED
)
set_target_properties( swresample-2
PROPERTIES IMPORTED_LOCATION
…/…/…/…/libs/armeabi-v7a/libswresample-2.so )
add_library(
swscale-4
SHARED
IMPORTED
)
set_target_properties( swscale-4
PROPERTIES IMPORTED_LOCATION
…/…/…/…/libs/armeabi-v7a/libswscale-4.so )
add_library(
postproc-54
SHARED
IMPORTED
)
set_target_properties( postproc-54
PROPERTIES IMPORTED_LOCATION
…/…/…/…/libs/armeabi-v7a/libpostproc-54.so )
add_library(
avfilter-6
SHARED
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
最后
今天关于面试的分享就到这里,还是那句话,有些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。
最后在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
【Android核心高级技术PDF文档,BAT大厂面试真题解析】
【算法合集】
【延伸Android必备知识点】
【Android部分高级架构视频学习资源】
Android精讲视频领取学习后更加是如虎添翼!进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
存中…(img-kYHCggs1-1711778091565)]
【Android部分高级架构视频学习资源】
Android精讲视频领取学习后更加是如虎添翼!进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!