如何在android studio导入so中导入JNI生成的.so库

1.使用NDK来生成so文件:
hello-jni.c
函数名Java +包名+函数名字
2.修改Android.mk文件
LOCAL_SRC_FILES :=hello-jni.c 指定c++文件
3.编译so文件
4.调用so文件
so文件copy到android项目的libs/armeabi下
最后输出一下结果:&&&&通过JNI调用第三方动态库(生成两个.so文件)
通过JNI调用第三方动态库(生成两个.so文件)
参考网上一些资料,实现了通过JNI调用第三方动态库.so,个人觉得重点在Make文件改写,例外注意确保程序完全正确,我开始就是程序中个字母写错而浪费了好多时间。
若举报审核通过,可奖励20下载分
被举报人:
举报的资源分:
请选择类型
资源无法下载
资源无法使用
标题与实际内容不符
含有危害国家安全内容
含有反动色情等内容
含广告内容
版权问题,侵犯个人或公司的版权
*详细原因:
VIP下载&&免积分60元/年(1200次)
您可能还需要
移动开发下载排行如何在 Android Studio 中包含 *.so library,并使用库中定义的方法? - 推酷
如何在 Android Studio 中包含 *.so library,并使用库中定义的方法?
需要 3 步:
Step1 把 .so file 放到 Android Studio project 正确的路径中
需要新建一个名为
文件夹,根据目标机器的 CPU-ABI 类型,把 .so file 放入对应的路径下:
weiyi$ cd app/src/main/
weiyi$ tree -L 2
├── AndroidManifest.xml
├── java
├── jniLibs
├── armeabi
└── libhello-jni.so
└── armeabi-v7a
└── libhello-jni.so
└── res
至于在其它编译器(eclipse等)中的路径,以及
armeabi-v7a
的解释,参考
.so file 需要通过 NDK tool 编译 c/c++ 得到,可以从
libhello-jni.so
Step2 加载 .so library 并声明 native method
Java 端实现加载 .so library:(HelloJni.java)
package com.example.hellojni;
public class HelloJni {
public native String stringFromJNI();
System.loadLibrary(&hello-jni&);
这篇开发文档
Step3 最后就可以调用 .so library native method 了
类似调用任何一个类的方法:
HelloJni helloJni = new HelloJni();
LOGD(TAG, helloJni.stringFromJNI());
可以看到 log:
Hello from JNI !
。而整个工程目录应该是这样:
weiyiWorkCell:main weiyi$ tree -L 5
├── AndroidManifest.xml
├── java
└── com
├── example
└── hellojni
└── HelloJni.java
├── jniLibs
├── armeabi
├── libhello-jni.so
└── armeabi-v7a
├── libhello-jni.so
└── res
UnsatisfiedLinkError: No implementation found
在 step2 时,假如把 native method 声明在了一个
的 package 或者随意命名的 java file 内,比如
com.example.hellojni21.HelloJni
,你会遇到如下 exception:
java.lang.UnsatisfiedLinkError:
No implementation found for java.lang.String com.example.hellojni21.HelloJni.stringFromJNI() tried
Java_com_example_hellojni21_HelloJni_stringFromJNI and
Java_com_example_hellojni21_HelloJni_stringFromJNI__
这是因为命名存在一个默认的规则。.so file 需要通过 NDK tool 编译 c/c++ 得到,c/c++ 实现 native method 时,要按如下规则命名,以 libhello-jni.so 为例:
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz )
规则如下:
Java_package_file_method(...)
所以,Java 端的包名、文件名、方法名就被规定好了,包名必须是
com_example_hellojni
,文件名必须是
,native method 声明必须是
String stringFromJNI()
这篇开发文档
描述了命名规则。
我们还可以通过命令行列出 shared library 中的方法:
weiyi$ nm -D libhello-jni.so
00000b90 T Java_com_example_hellojni_HelloJni_stringFromJNI
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致android studio 编译C生成.so文件
前段时间有个同事离职了,用C编译的.SO文件需要更改,结果C文件是他写的,无赖啊,自己又是一个小白,不会啊,所以自己又好好钻研了一天,不会,看什么都难啊,痛苦啊,网上找了好多,才找到的,而且感觉都不怎么详细,步骤说的不是很清楚,所以自己整理了一下,谁便记录一下,好了,废话不多说,开始正题。
二、编译过程
1、编译环境的搭建
正所谓:&工欲善其事必先利其器&嘛,所以先把改准备工具准备一下,因为是在studio下编译的,所以啊,什么studio、什么sdk、什么jdk,这些都自己去弄吧,这里说一下ndk这个编译C文件工具怎么下载安装;
下载链接:(一般需要翻墙,至于原因嘛,你懂得)进去之后下载自己相对应的ndk平台版本;
下载完了之后直接是一个zip的压缩包,解压即可;
然后如下图所示的配置ndk:
然后你会在local.properties文件中看到:
不要急,还没有完,ndk环境搭建还有最后一步,在gradle.properties的文件末尾加上android.useDeprecatedNdk=true这段代码,文字看不懂吧直接上图:
好了,到此处环境就搭建完毕了。
2、java代码和C代码的编写步骤及过程
首先新建一个java类JNIUtils.java
public class JNIUtils {
System.loadLibrary(&huazict&);
//java调C中的方法都需要用native声明且方法名必须和c的方法名一样
public native String getString();
然后如下图所示重新Make Project一下工程:
会在工程目录E:\work\MyApplication\stujni\build\intermediates\classes\debug\com\huazi\stujni\jni中看到自己编译后的class文件JNIUtils.class如下图所示:
其次就是生成.h文件了
在studio打开Terminal命令行工具,打开步骤是View-&Tool Windows-&Terminal (或直接按Alt+F12),如下图所示:
然后在命令行中先进入到工程的main目录下
输入命令:javah -d jni -classpath 自己编译后的class文件的绝对路径
例如:javah -d jni -classpath E:\work\MyApplication\stujni\build\intermediates\classes\debug com.huazi.stujni.jni.JNIUtils(注意debug后的空格)
看到上图,图中命令行中是直接进入到了工程的main目录下(在哪个目录下运行就会在哪个目录下自动生成jni文件夹),按回车之后就会在main目录下生成jni文件夹,同时生成.h文件,如下图:
这个文件.h文件不需要做任何修改,默认即可。
现在我们来写一个test的C文件huazict.c同.h文件一样放到jni文件夹下,代码如下:
#include &com_huazi_stujni_jni_JNIUtils.h&
* 上边的引用标签一定是.h的文件名家后缀,方法名一定要和.h文件中的方法名称一样
JNIEXPORT jstring JNICALL Java_com_huazi_stujni_jni_JNIUtils_getString
(JNIEnv *env, jobject obj) {
return (*env)-&NewStringUTF(env, &这是我测试的jni&);
如图所示:
最后在构建文件中的默认配置中加上:
//ndk编译生成.so文件
moduleName &huazict&
//生成的so名字
abiFilters &armeabi&, &armeabi-v7a&, &x86&
//输出指定三种abi体系结构下的so库。
到这里,通过jni调C就完成了,现在我们来测试一下,写个TextView显示一下调用的C:
public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView)findViewById(R.id.tv);
tv.setText(new JNIUtils().getString());
看效果,直接上图:
ok,没问题,可以调用,其实也没有想象中的那么难,是吧!
三、调用编译过的.so库
上边编译完成了,有人会问:我要的是编译后的.so库,别人用的时候直接拿来用就可以了,那编译后的.so库在哪呢?不要着急请看下图:
根据这个路径就可以找到指定输出的三种体系结构下的.so库文件,然后把.so文件复制出来,如下图所示的放到相应的文件夹下就ok了:
再次运行,结果还是一样的,跟上边贴的那张图的显示效果是是一样的,同样能调用到,代码我就不上传了,都在上边贴上去了,而且也上传不了,公司的所有文件都是加密的,想上传都上传不了。
到这里,整个jni的调用过程就结束了,包括调用jni需要的环境以及调用的过程,最后.so文件的导出,都在上边了,如果上边的jni调用过程有什么问题,欢迎留言,谢谢。
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'如何在Android Studio中导入JNI生成的.so库_百度知道

我要回帖

更多关于 android jni生成so 的文章

 

随机推荐