androidnativeapi在AndroidStudio3.1.4下面编译的方法
如何编译webrtc请参考官网。步骤很简单,就是下载比较麻烦,需要翻墙,而且文件比较多也比较大,webrtc_android一共有20G左右吧。
BTW,由于webrtc项目才开始接触android,之前一直是在做后台C/C++相关的开发。我参考的是android编译方法,我的本地工作环境:
- OS:
ubuntu 16.04 - 翻墙工具
lantern pro版,优点是:不限流量。缺点:收费,且不够稳定,长时间(好几天吧)开启后会出现无法翻墙的问题,需要重启lantern程序。
言归正传,假设你已经编译好了webrtc相关工程,那么,在src/out/arm64(假设你编译的android target cpu为arm64)目录下会生成很多文件,其中就包括libwebrtc.a及libjingle_peerconnection_so.so库,在此按照我个人的理解来解释一下这两个库:
- libwebrtc.a
利用命令:nm -C -g --defined-only libwebrtc.a查看库中包含的符号,你们发现基本所有的API都包含在里面,所以说,它可以作为ndk开发的依赖库。 - libjingle_peerconnection_so.so
利用命令:nm -C -g --defined-only libjingle_peerconnection_so.so查看它所包含的符号,发现很少,而且仅包括类似Java_org_webrtc_xxxxx相关的符号,该库应该是与webrtc java SDK匹配使用的,它并不能作为ndk开发的依赖库。
OK,接下来到了我最关心的androidnativeapi这个demo,按照官网的编译方法是完全可以生成androidnativeapi.apk的,但安装的手机上去无法正常使用,我急切想要把源码放在androidstudio下面自己编译及调试,我也有参考官网中提供的方法,即如何把androidnativeapi导出到androidstudio工程下面,可能是我的英文水平和理解能力有限,最后以失败告终。
但是,有源码,有相关的依赖库,为何不能自己创建一个androidnativeapi工程?说干就干,具体步骤如下:
-
创建一个空白的android studio工程,一路next:
-
把webrtc中的androidnativeapi demo中的源码及其它所有配置项都copy到刚创建好的工程中对应的目录并替换
-
打包aar:进行到webrtc/src目录中,执行命令:
./tools_webrtc/android/build_arr.py
,运行它需要很长时间,之后在当前目录下会生成libwebrtc.aar -
获取webrtc ndk开发所需要的头文件:在webrtc/src/…/目录中创建一个shell脚本,内容如下:
#!/bin/bash mkdir -p inc src=`find src/ -name "*.h"` mkdir inc for obj in $src do cp --parents $obj inc/ done
此时inc中包含ndk开发所需要的所有头文件(当然还包含一些不需要的头文件,自己视情况删减)。
-
配置创建好的androidnativeapi工程的libs:把inc,libwebrtc.aar,libwebrtc.a,libjingle_peerconnection_so.so拷贝到libs目录,目录结构如下(我已经适配了android全平台了):
-
配置build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "org.webrtc.examples.androidnativeapi"
minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
arguments = ['-DANDROID_STL=c++_static']
cppFlags "-std=c++11 -fno-rtti"
}
}
ndk {
abiFilters "arm64-v8a","armeabi-v7a","x86_64","x86"
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
sourceSets {
main {
// 1. 配置在根目录libs下可以加载第三方so库, (最好不要创建jniLibs, 在众多的开源库中可能会引起冲突,还没发现)
// 2. 运行时会自动将libs目录下的so库拷贝到指定目录
// 3. 如果自己创建的so不需要重新编译,可以将(app/build/intermediates/transforms)生成的so拷贝到这个目录
jniLibs.srcDirs = ['libs']
// 如果是单个文件夹 可以直接这样如下配置
// jniLibs.srcDir 'libs'
}
}
buildToolsVersion '28.0.2'//新增
}
repositories {
flatDir{
dirs'libs'
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:28.0.0-rc02'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation(name: 'libwebrtc', ext: 'aar')
}
7.配置CMakeLists.txt
# 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)
# 设置工程的全路径
set(CWD ${CMAKE_CURRENT_LIST_DIR})
#add_definitions(-DV8_DEPRECATION_WARNINGS -DNO_TCMALLOC -DSAFE_BROWSING_DB_REMOTE -DCHROMIUM_BUILD -DFIELDTRIAL_TESTING_ENABLED -D_GNU_SOURCE -DANDROID -DHAVE_SYS_UIO_H -DANDROID_NDK_VERSION_ROLL=r16_1 -DCR_CLANG_REVISION=\"340925-2\" -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__GNU_SOURCE=1 -DCHROMIUM_CXX_TWEAK_INLINES -D_DEBUG -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DWTF_USE_DYNAMIC_ANNOTATIONS=1 -DWEBRTC_ENABLE_PROTOBUF=1 -DWEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE -DHAVE_SCTP -DUSE_BUILTIN_SW_CODECS -DWEBRTC_ARCH_ARM64 -DWEBRTC_HAS_NEON -DWEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS=1 -DWEBRTC_POSIX -DWEBRTC_LINUX -DWEBRTC_ANDROID -DABSL_ALLOCATOR_NOTHROW=1 -DHAVE_WEBRTC_VIDEO -DHAVE_WEBRTC_VOICE)
add_definitions(-DWEBRTC_POSIX)
include_directories(${CWD}/libs/inc/webrtc)
include_directories(${CWD}/libs/inc/webrtc/third_party/abseil-cpp)
include_directories(${CWD}/libs/inc/webrtc/out/Debug/gen)
include_directories(${CWD}/libs/inc/webrtc/out/Debug/gen/examples/androidnativeapi/generated_jni)
# 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.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
src/main/cpp/androidcallclient.cc
src/main/cpp/onload.cc)
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
find_library( # Sets the name of the path variable.
OpenSLES-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
OpenSLES )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
native-lib
#android
${CWD}/libs/${ANDROID_ABI}/libwebrtc.a
${CWD}/libs/${ANDROID_ABI}/libjingle_peerconnection_so.so
# Links the target library to the log library
# included in the NDK.
${OpenSLES-lib}
${log-lib}
)
到此,我已经可以正确的生成APK了,且在手机上可以正常运行,分享一下APP运行过程中的截图:
由于该工程中的库及头文件比较大,也没来得及删减,所以暂时没有push到git中,等到十一放假在做整理,上传到git中,供大家参考,如有疑问,欢迎留言