cmake_minimum_required(VERSION 3.4.1)
#定义全局 my_source_path 变量
file(GLOB my_source_path
${CMAKE_SOURCE_DIR}/.cpp
${CMAKE_SOURCE_DIR}/.c)
add_library(toly_facer-lib
SHARED ${my_source_path})
find_library(log-lib log)
target_link_libraries(toly_facer-lib ${log-lib})
4.设计JNI的native接口方法和C++实现
此方法所属类名、包名对user都至关重要。对于creator随意啦,就是任性
---->[src/main/java/com/toly1994/jni_creator/Facer.java]----
package com.toly1994.jni_creator;
public class Facer {
public static native String getFacer( String top, String bottom, String brow, String eyes);
}
C++与Java的相互作用,就是Java进行输入,经
C++
转化将有价值的东西传给Java端
---->[src/main/cpp/toly_facer-lib.cpp]----
#include <jni.h>
#include
#include “Facer.h”
extern “C”
JNIEXPORT jstring JNICALL
Java_com_toly1994_jni_1creator_Facer_getFacer(JNIEnv *env, jclass clazz, jstring top,
jstring bottom, jstring brow, jstring eyes) {
Facer facer(//使用 env->GetStringUTFChars将jstring转化为string
env->GetStringUTFChars(top, 0),
env->GetStringUTFChars(bottom, 0),
env->GetStringUTFChars(brow, 0),
env->GetStringUTFChars(eyes, 0)
);
return env->NewStringUTF(facer.getFace().c_str());
}
基本上流程就是这样。
三、扫盲科普
1.arm64-v8a、armeabi-v7a、x86、x86_64
arm 架构注重的是续航能力:大部分的移动设备
x86 架构注重的是性能:大部分的台式机和笔记本电脑
arm64-v8a :第8代、64位ARM处理器
armeabi-v7a :第7代及以上的 ARM处理器
x86:x86 架构的 CPU(Intel 的 CPU)
x86_64:x86 架构的64位 CPU(Intel 的 CPU)
默认会编译出四种.so文件
2.配置输出的.os架构类型
可以通过
app下的build.gradle
来指定编译的.so类型
注意只有这四种类中
,以前很多项目中存在abiFilters 'armeabi'
但现在会崩
android {
defaultConfig {
externalNativeBuild {
cmake {
abiFilters ‘armeabi-v7a’, ‘arm64-v8a’
}
}
}
这样清一下项目,再编译出来的只有
'armeabi-v7a', 'arm64-v8a'
此时运行到模拟器上,会发现找不到类库,则说明模拟器去X86的。运行到真机无误,则说明真机是arm的
3..so
文件是什么?
如果说
.dll
估计你会说:哦,好像见过
。
其实.so
和.dll
并没有本质的区别,它们都是一个C++实现的功能团
。
只不过.so
是用在linux上的,.dll
是用在Windows上的。
如今操作系统三足鼎立,当然少不了MacOS,类似的在MacOS中有.dylib
文件。
它们都是 C++
的动态链接库(Dynamic Link Library )
而Android作为Linux的一员,
C++
编译出的.so
便是顺理成章
那如何将C++编译成.so库
?这便是NDK在做的事,也是上面在做的事。
打包时gradle会将对应的.so包打到apk里,然后.so就能在linux里愉快的玩耍了。
4.如何自定义资源文件位置
个人建议
习惯优于配置
,用默认挺好的。如果你是非常有个性的…也可以在gradle里进行制定
虽然你也许不会用到,但是看一下,看到要认得,不至一脸蒙圈。
对于使用者,可以随意指定盛放.so
的文件夹,需要在app下的build.gradle
配置
android {
…
sourceSets {
main {
jniLibs.srcDirs = [‘target’]//指定so库的位置,加载so库
}
}
}
对于创造者,也可以使用
jni.srcDirs
来指定C++代码盛放的位置
sourceSets.main{
jni.srcDirs = [“src/main/cpp”]
}
四、对于程序设计师(Designer)
俗话说
难的不是重写,而是对烂代码的重构
,有时候修改比创作更难
已有的.so文件
但功能上又需要定制,于是第三类就诞生了,也是最头疼的
其实FFmpeg和OpenCV等都是这第三类,用已存在事物去构建新事物,便是设计。
1.项目结构
算法和核心代码已经实现,我们需要做的是结合业务进行接口封装及方法调用
这里我就用OpenCV的使用来进行演示: 你需要创建的是Native C++项目
(Opencv下载什么的,不废话了,详见:OpenCV专题1 - AndroidStudio的JNI工程及引用OpenCV)
2.你的角色
这时,你是设计者,兼具创造者和使用者两重角色。但比纯粹的创造要简单,比纯粹的使用要难。
这时可以通过CmakeLists
去链接到OpenCV的.so文件,这样你就可以使用OpenCV的头文件进行功能实现
cmake_minimum_required(VERSION 3.4.1)
include_directories(include)#引入include文件夹
#定义全局 my_source_path 变量
file(GLOB my_source_path ${CMAKE_SOURCE_DIR}/.cpp ${CMAKE_SOURCE_DIR}/.c)
aux_source_directory(. my_source_path) #上行的简化:将本文件夹下文件加入
add_library(toly_cv SHARED ${my_source_path})
#添加动态链接库
add_library(lib_opencv SHARED IMPORTED)
set_target_properties(lib_opencv PROPERTIES IMPORTED_LOCATION
C
M
A
K
E
S
O
U
R
C
E
D
I
R
/
.
.
/
j
n
i
L
i
b
s
/
{CMAKE_SOURCE_DIR}/../jniLibs/
CMAKESOURCEDIR/../jniLibs/{ANDROID_ABI}/libopencv_java4.so) #so文件位置
在ndk中查找log库 取别名log-lib
find_library(log-lib log)
在ndk中查找jnigraphics库 取别名jnigraphics-lib jnigraphics
find_library(graphics jnigraphics)
target_link_libraries(
toly_cv
lib_opencv
jnigraphics
log
)
你可以定义一个JNI接口来暴露你在C++层实现的方法,再打包成.so供他人使用
这便是开源的魅力,比如下面的灰色图像,使用者可以拿着打出的.so包通过TolyCV来使用
---->[com.toly1994.jni_designer.TolyCV]----
public class TolyCV {
public static native Bitmap grayBitmap(Bitmap bitmap,Bitmap.Config argb8888);
}
---->[src/main/cpp/toly_cv.cpp]----
#include <jni.h>
#include
#include “bitmap_utils.h”
#include <opencv2/imgproc/types_c.h>
extern “C”
JNIEXPORT jobject JNICALL
Java_com_toly1994_jni_1designer_TolyCV_grayBitmap(JNIEnv *env, jclass clazz, jobject bitmap,jobject argb8888) {
Mat srcMat;
Mat dstMat;
bitmap2Mat(env, bitmap, &srcMat);
cvtColor(srcMat, dstMat, CV_BGR2GRAY);//将图片的像素信息灰度化盛放在dstMat
return createBitmap(env,dstMat,argb8888);//使用dstMat创建一个Bitmap对象
}
五、让人糟心的异常
笔者也并非一路畅通无阻,走的坑也挺多,下面几个坑来给你说说
1.ninja: error: 巴拉巴拉… missing and no known rule to make it
仔细排查
CmakeLists
,可能是.so文件的路径不对
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
最后
跳槽季整理面试题已经成了我多年的习惯!在这里我和身边一些朋友特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。
附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)
[外链图片转存中…(img-D7GCmbKl-1712783736122)]
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-OkP2jSZ2-1712783736122)]