android ndk开发经常遇到了动态库的问题,本文主要介绍:

① 动态链接库的生成;

② 在Java和C混合编程的情况下如何调用第三方动态链接库;

③ 通过jar包的方式间接调用第三方动态链接库;

④ 使用dlopen程序运行时直接调用;

⑤ 纯c的方式开发调用;

本文重点推荐②和⑤,第④中太麻烦每个函数都需要dlsym调用一次,第③中主要用在有第三方jar包的情况下;

方便他人亦是方便自己,如果觉得还行就点下右边的投票吧,这样可以帮助其他人更快的找到解决问题的方法;有疑问的也可留言哦, 谢谢!

代码的百度云链接:http://pan.baidu.com/s/1dD3qkQ9 密码:c5s3

工具/原料

Win7 x64

adt-bundle-windows-x86_64-20140702

android-ndk-r10

生成动态库

1

android ndk下面生成动态库so文件的方法很多,但是这里只提供一种方法,更多的生成方法可以看,“ndk 编译静态库”:

http://jingyan.baidu.com/article/63f236280b90690208ab3d12.html

2

fkAdd.c 的内容如下:

#include

int fkAdd(int nX, int nY)

{

returnnX + nY;

}

3

Android.mk 的内容如下:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE:= fkAdd

LOCAL_SRC_FILES:= fkAdd.c

include $(BUILD_SHRRED_LIBRARY)

4

1、打开 eclipse

2、点击 文件

3、点击 新建

4、点击 other...

5

1、展开 Android 选项;

2、选择 Android Project from Existing Code;

3、点击 Next

6

1、输入 Root Director;

2、取消 tests;

3、选中 Copy projects into workspace;

4、点击 Finish;

7

1、右键工程;

2、选择 Android Tools;

3、Add Native Support...;

8

点击 Finish

9

修改android sdk 版本为 4.0.3;

关于如何修改 android sdk 版本:

http://jingyan.baidu.com/article/c910274bfdd000cd371d2d4b.html

10

修改 Min SDK version:15

修改 Target SDK version:19

11

在jni目录下面新建文件fkAdd.c 的内容如下:

int fkAdd(int nX, int nY)

{

returnnX + nY;

}

12

临时修改 Android.mk 文件内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

#LOCAL_MODULE := hello-jni

#LOCAL_SRC_FILES := hello-jni.c

LOCAL_MODULE := fkaddso

LOCAL_SRC_FILES := fkAdd.c

include $(BUILD_SHARED_LIBRARY)

13

使用快捷键Ctrl+B编译后可以在libs目录下面看到生成的一些列的

libfkaddso.so文件,如下图所示

END

Java和c编程调so

1

1、将libs复制一份到jni目录下面,删掉其中不相关的文件

2、删掉文件 jni/fkadd.c 文件

3、将 Android.mk 文件还原成最开始的样子;

2

修改 hello-jni.c 中的部分代码,如下:

char szMsg[1024] = {0};

int nSum = fkAdd(100, 10);

sprintf (szMsg, "Hello from JNI ! Compiled with ABI " ABI ". %d ", nSum);

return (*env)->NewStringUTF(env, szMsg);

3

修改 Android.mk 文件:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := fkaddso

LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libfkaddso.so

include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE := hello-jni

LOCAL_SRC_FILES := hello-jni.c

LOCAL_SHARED_LIBRARIES := fkaddso

include $(BUILD_SHARED_LIBRARY)

4

修改 HelloJni.java 在其中增加一行:

System.loadLibrary("fkaddso");

5

运行工程看效果:

END

用jar调用so

1

菜单->File->New->Android Application Project

2

创建一个没有主题的android project

3

1、取消复选框 Create activity

2、选择复选框 Mark this project as a library

3、Next

4

点击 Next

5

点击 Finish

6

新建一个类: NativeSo,包名:fuke.nativeso

7

在 NativeSo.java 中添加如下内容:

package fuke.nativeso;

package fuke.nativeso;

public class NativeSo {

static {

System.loadLibrary("fkaddso");

System.loadLibrary("nativeso");

}

public static native int GetTestValue();

}

8

1、右键工程->Anroid Tools->Add Native Support

2、将 生成动态库 部分生成的jni目录下面的: libs目录,Android.mk,Application.mk 三个文件拷贝到本工程的jni目录下面

3、修改 Android.mk中的内容为:

LOCAL_PATH := $(call my-dir)

### 把动态链接库重新名一个模块名

include $(CLEAR_VARS)

LOCAL_MODULE := fkaddso

LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libfkaddso.so

include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE := nativeso

LOCAL_SRC_FILES := NativeSo.c

LOCAL_SHARED_LIBRARIES := fkaddso

include $(BUILD_SHARED_LIBRARY)

9

通过javah生成 fuke_nativeso_NativeSo.h,关于如何利用javah生成native方法对应的头文件,见“ndk java 和 c 互掉”:

http://jingyan.baidu.com/article/f54ae2fcde72be1e92b84916.html

10

在 NativeSo.c 文件中添加内容:

#include

#include "fuke_nativeso_NativeSo.h"

extern int fkAdd(int nX, int nY);

JNIEXPORT jint JNICALL Java_fuke_nativeso_NativeSo_GetTestValue

(JNIEnv *pJniEnv, jclass pJclass){

returnfkAdd(100, 1000);

}

11

Application.mk 中内容如下:

APP_ABI := all

12

按照 生成动态库部分中的1-10这10个步骤导入ndk测试用例 HelloJni

13

1、右键工程属性

2、选择android分页

3、增加 NativeSo 库

4、点击Apply

5、点击OK

14

修改 HelloJni.java 文件的方法 onCreate:

tv.setText( stringFromJNI() + NativeSo.GetTestValue());

15

编译运行后效果如下:

16

在 HelloJni.java 中增加:

System.loadLibrary("fkaddso");

System.loadLibrary("nativeso");

删除 NativeSo.java 中删除对应的几行:

17

为了方便验证修改下过,修改 NativeSo.c 中的数据:

returnfkAdd(100, 999);

18

编译运行后的效果如下:

END

用dlopen调用so

1

重复“生成动态库”中的过程1到10,

2

把需要调用so文件的目录libs拷贝到jni目录下面,并修改 Android.mk 文件的内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := fkaddso

LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libfkaddso.so

include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE := hello-jni

LOCAL_SRC_FILES := hello-jni.c

include $(BUILD_SHARED_LIBRARY)

3

修改 hello-jni.c 的内容如下:

char*szSo = "/data/data/com.example.hellojni/lib/libfkaddso.so";

void* fkAddSo = dlopen(szSo, RTLD_LAZY);

int (*fpAdd)(int,int) = (int (*)(int,int))dlsym(fkAddSo, "fkAdd");

char szMsg[1024] = {0};

int nSum = fpAdd(100, 200);

dlclose(fkAddSo);

sprintf (szMsg, "%s %d", szSo, nSum);

return (*env)->NewStringUTF(env, szMsg);

4

关于如何获取 so在手机中的路径,可以通过在控制台下输入 adb shell 后,

在手机上查询:

5

编译后运行效果:

6

方便他人亦是方便自己,如果觉得还行就点下下边的投票吧,这样可以帮助其他人更快的找到解决问题的方法;有疑问的也可留言哦, 谢谢!

END

纯c的方式开发调用

1

此方法需要感谢ndk吧的吧友提供哦,本人只是负责将其进行了整理,归纳后发帖,谢谢,原始地址:http://tieba.baidu.com/p/3247530080

2

根据“生成动态库”中的过程1到10,新建一个纯c的ndk程序:

“D:\Android\android-ndk-r10\samples\native-activity"

3

把会用的so文件的目录libs拷贝到 jni目录下面

4

修改 Android.mk 文件,内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := fkAdd

LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libfkAdd.so

include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE := main

LOCAL_SRC_FILES := main.c

LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv1_CM

LOCAL_STATIC_LIBRARIES := android_native_app_glue

LOCAL_SHARED_LIBRARIES := fkAdd

include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE := native-activity

LOCAL_SRC_FILES := NativeActivity.c

LOCAL_LDLIBS := -llog -landroid

LOCAL_STATIC_LIBRARIES := android_native_app_glue

include $(BUILD_SHARED_LIBRARY)

$(call import-module,android/native_app_glue)

5

增加 NativeActivity.c 文件,添加内容如下:

#include

#include

#include

#include

void android_main(struct android_app* state) {

// Make sure glue isn't stripped.

app_dummy();

void* soAdd = dlopen("/data/data/com.example.native_activity/

lib/libfkAdd.so",RTLD_NOW);

void* soMain = dlopen("/data/data/com.example.native_activity/

lib/libmain.so",RTLD_NOW);

void (*fp_android_main)(struct android_app*) =

(void (*)(struct android_app*))dlsym(soMain,"android_main");

fp_android_main(state);

dlclose(soMain);

dlclose(soAdd);

}

6

在 main.c 文件中添加一行,方便测试:

__android_log_print(ANDROID_LOG_DEBUG, "fuke", "engine_handle_input 100 + 200 = [%d] ", fkAdd(100, 200));

7

编译运行,点击手机屏幕后,观察logcat 效果如下:

END

注意事项

c++的函数在写动态链接库的时候,需要注意的是c++的函数会被系统修改,所以做动态库测试的使用最好用c语言

android ndk 动态库_百度经验,android ndk 动态库相关推荐

  1. android 系统gpu 调试_基于Android系统的GPU动态调频方案 | Imagination中文技术社区

    针对移动终端上GPU的高功耗问题,提出一种基于Android系统的GPU动态调频方案.方案根据各种应用对GPU的性能需求,引入了GPU的频率一性能模型,包括选择工作频率和测量相对性能的方法.动态调频算 ...

  2. android mvp模式例子_关于Android市场这件事,没有饱和的市场只有饱和的思维

    前言 早在几年之前,我们就一直在讨论Android程序员已经饱和的这个问题,直到2020年,Android程序员也没有饱和,相反对高级程序员的需求越来越大. 为什么会有Android程序员已经饱和的错 ...

  3. android sdk方法隐藏_每个Android开发都必须知道的利器

    1.背景介绍   在移动端项目功能不断完善和丰富的过程中我们一直在寻找一种可以高效开发且复用率高的开发模式,特别是多应用同步开发.管理.   在开发过程中你是否遇到需要发布影子工程?新建项目是否需要耗 ...

  4. android 动画 最顶层_【Android编程实战】StrandHogg漏洞复现及原理分析_Android系统上的维京海盗...

    0x00 StrandHogg漏洞详情 StrandHogg漏洞 CVE编号:暂无 [漏洞危害] 近日,Android平台上发现了一个高危漏洞 该漏洞允许攻击者冒充任意合法应用,诱导受害者授予恶意应用 ...

  5. android开发java环境_搭建Android开发环境 - Android - mobile - JavaEye论坛

    Android的开发现在是如火如荼,逞现在不是很忙了,学习了下,这里记录下了在windows在如何搭建Android开发环境,对自己是个记录,对新入门的兄弟姐妹们可以参考一下! (1)安装JDK,省略 ...

  6. android实现评论列表_【Android视图效果】分组列表实现吸顶效果

    效果图 效果图 分析 先来分析一下,可以看到这是一个按月份分组的2行图片列表,列表顶部一个悬浮栏,会随着列表滑动而刷新,点击顶部栏,弹出了一个筛选框. 思路 1.列表部分 可以用RecyclerVie ...

  7. android淡入淡出动画_在Android中淡入动画示例

    android淡入淡出动画 1) XML File: activity_main 1)XML文件:activity_main <?xml version="1.0" enco ...

  8. bazel 链接第三方动态库_如何自己制作静态库?

    前言 在<一文带你了解静态库和动态库>一文中介绍了静态库的特点以及与动态库的区别.那么你有没有想过如何把自己写好的函数接口制作成静态库给别人用呢?本文教你如何制作属于自己的静态库. 编译成 ...

  9. android 同根动画_[转载]Android anim动画切换效果

    关于动画的实现,Android提供了Animation,在Android SDK介绍了2种Animation模式: 1. Tween Animation:通过对场景里的对象不断做图像变换(平移.缩放. ...

最新文章

  1. 新闻发布项目——业务逻辑层(newsTbService)
  2. 胳膊上无缘无故起了个大包
  3. 神经网络早期的M-P(Warren McCulloch-Walter Pitts)模型
  4. python里面对文件的读写操作
  5. c 普通的文本变成注释文本的快捷键_IntelliJ Idea 常用快捷键列表 (2019年总结)
  6. 《机器学习实战》总结
  7. csv 中显示逗号和双引号
  8. 服务器维修质保合同,服务器维护保修合同(标准版本).pdf
  9. 数字图像处理基础与应用学习,第二章
  10. linux动态库加载RPATH,RUNPATH
  11. Scala 语法基础
  12. python---之os.path.split()函数
  13. webService发布和调用--Axis2
  14. VMware虚拟机中windows7系统的安装
  15. python pandas ewm 一次指数加权移动平均
  16. 思科交换机dhcp配置
  17. 建立主DNS区域和辅助DNS区域的最佳实践
  18. 程序猿520python表白利器——丘比特之箭
  19. c和cpp实现CPU核上绑定固定线程
  20. 记 Linux 学习知识总结 -- 寒江老师视频(七) - SHELL 讲解

热门文章

  1. 三星a9s参数_三星a9参数详细参数
  2. 一品多码商品档案建立,相同商品有多个不同的条码的进销存管理
  3. 软件测试三阶段,你在哪一步?
  4. ios 自动缩小字体_iOS 字体自适应屏幕大小
  5. While 与 Do...While...
  6. vue+springboot保存头像
  7. IoT入门概述与物联网安全基础
  8. 转 5种Linux屏幕录像的方法
  9. 关于信息论中熵的定义与含义:
  10. CSS设置溢出文字显示省略号