笔沫

有梦为马,随处可栖

  • 主页
  • 技术
  • 随想
  • 音乐
所有文章 其他

笔沫

有梦为马,随处可栖

  • 主页
  • 技术
  • 随想
  • 音乐

Android studio NDK编译及so库生成方法讲解

2017-06-30

前言:在Android开发的eclipse时代,想要开发NDK项目或生成so库,是非常蛋疼的,需要踩坑无数,方能生成so库;而如今Android Studio时代,开发jni C/C++项目,通过gradle的集成工具,那是一个爽。下面将会介绍两种利用AS和gradle开发NDK项目及生成so库的方式。

一.环境准备

Android开发环境,Android-SDK,java-SDK,android-NDK相关环境(略:网上有许多)

1.安装完成之后如图:

2.在项目的gradle.properties文件中加上 android.useDeprecatedNdk = true

3.注意写好native接口和System.loadLibrary()

如:JNIUtil和MainActivity

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class JNIUtil {
private static JNIUtil instance = new JNIUtil();
public static JNIUtil getInstance() {
return instance;
}
static {
System.loadLibrary("native-lib");
}
public native String initData();
public native String getStringFromJni();
}
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView) findViewById(R.id.sample_text);
tv.setText(JNIUtil.getInstance().getStringFromJni());
Log.i("笔沫拾光",JNIUtil.getInstance().initData());
Toast.makeText(this,JNIUtil.getInstance().initData(),Toast.LENGTH_LONG);
}
}

二.两种编译和生成SO库的方式

1.手动编译C/C++文件和so库生成

i.生成C/C++文件

执行Build->Make Project,生成class文件,class文件的生成路径为: app_path/build/intermediates/classes/debug.

javah生成c头文件

操作命令:
javah -d jni -classpath SDK_android.jar;APP_classes lab.sodino.jnitest.MainActivity

代码示例:

1
javah -d jni -classpath D:\sdk\platforms\android-25\android.jar;E:\githup\JniTest\app\build\intermediates\classes\debug com.awen.jnitest.JNIUtil

生成头文件如图:

ii.编辑C文件
在main.c文件中实现头文件中的方法

代码示例C:

1
2
3
4
5
6
7
8
9
10
11
#include "com_awen_jnitest_JNIUtil.h"
JNIEXPORT jstring JNICALL Java_com_awen_jnitest_JNIUtil_initData(JNIEnv *env, jobject jObj){
return (*env)->NewStringUTF(env, "有梦为马,随处可栖。");
}
JNIEXPORT jstring JNICALL Java_com_awen_jnitest_JNIUtil_getStringFromJni
(JNIEnv *env, jobject jObj){
return (*env)->NewStringUTF(env, "笔沫拾光\nhttp://awenzeng.me/");
}

代码示例C++:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <jni.h>
#ifdef __cplusplus
extern "C" {
#endif
jstring Java_com_awen_jnitest_JNIUtil_initData(JNIEnv *env, jobject jObj){
return env->NewStringUTF("Hello NDK C++");
}
jstring Java_com_awen_jnitest_JNIUtil_getStringFromJni
(JNIEnv *env, jobject jObj){
return env->NewStringUTF("笔沫拾光\nhttp://awenzeng.me/");
}
#ifdef __cplusplus
}
#endif

iii.修改build.gradle配置

代码示例:

1
2
3
4
ndk {
moduleName "native-lib"
abiFilters "armeabi", "armeabi-v7a", "x86"//控制so库生成兼容的平台
}

具体如图

iV.执行Build->Rebuild Project或Make Project,so库就会自动生成,具体如图:

2.Android studio配置工具编译和生成so库

i.Android studio工具配置

为了方便生成头文件和so文件,我们可以在Android Studio → External Tools中设置两个命令,分别来生成头文件和生成.so文件

javah:

具体配置代码:

1
2
3
4
5
6
7
8
Program:
$JDKPath$/bin/javah
Parameters:(具体参数参考第一种方法头文件的生成)
-d jni -classpath D:\sdk\platforms\android-25\android.jar;E:\githup\JniTest\app\build\intermediates\classes\debug $FileClass$
Working
$SourcepathEntry$\..\java

ndk-build:

具体配置代码:

1
2
3
4
5
6
7
8
Program:
D:\sdk\ndk-bundle\build\ndk-build.cmd
Parameters:
NDK_LIBS_OUT=$ModuleFileDir$/libs APP_ABI=armeabi-v7a,armeabi,x86
Working
$ModuleFileDir$\src\main

ii.C/C++文件生成及so库生成

头文件.h的生成,具体操作如图:

具体步骤:

选中JNIUtil点击右键,显示如上图,选中NDK,点击javah,就会自动生成头文件,具体位置如图:

.c文件生成和第一种一样(这里略)

so库文件生成,点击ndk-build,生成库文件,具体如图:

到此,两种方法生成讲解完毕。

三.注意事项

第一种方式

  • gradle.build中生成so库文件的平台可配置,如(具体如第一种方式build配置):abiFilters “armeabi”, “armeabi-v7a”, “x86”//控制so库生成兼容的平台
  • 生成的so库是在build文件中,需要手动copy到项目。

第二种方式

  • 在ndk-build的配置中,so库文件生成平台也可以配置,如(具体如ndk-build配置):APP_ABI=armeabi-v7a,armeabi,x86
  • so库文件的生成位置是可以配置的,自动生成到你配置的位置(这一点爽爆了,不用copy),如(具体如ndk-build配置):NDK_LIBS_OUT=$ModuleFileDir$/libs
  • 可以随时修改C/C++代码,然后点击ndk-build生成so库,直接调试,非常方便。

源码地址,欢迎下载及Star

https://github.com/awenzeng/JniTest

四.参考文献

android studio NDK使用,编译c生成.so实践记录

Android Studio开发JNI工程

Android NDK Jni 开发C和C++的区别

赏

感谢认可,么么哒

支付宝
微信
  • 技术
  • Android
  • NDK
  • JNI C/C++

扫一扫,分享到微信

微信分享二维码
我之存在,因为有你
你本是一个肉体,是什么驱使你前行[1]
© 2019 笔沫
Hexo Theme Yilia by Litten
  • 所有文章
  • 其他

tag:

  • 技术
  • Android
  • Activity的启动模式
  • Android注解
  • Java反射机制
  • Java动态代理
  • Android基础
  • MVP
  • NDK
  • JNI C/C++
  • 开源框架
  • AS Gradle优化
  • 博客搭建
  • 设计模式
  • Fragment
  • Rxjava
  • Rxandroid
  • 响应式编程
  • 随想
  • 你本是一个肉体,是什么驱使你前行
  • 原创
  • 笔沫拾光
  • Java
  • Java基础
  • 王阳明心学
  • 中国历史
  • 人生的意义
  • 演讲
  • 执着的人是幸福的
  • 郭川
  • Android框架源码解析
  • 加解密算法
  • Binder通信机制
  • 开源框架源码解析
  • LeakCanary框架源码分析
  • Java集合类
  • 转载
  • Http文件断点续传
  • Logger框架源码解析
  • Android应用程序入口源码解析
  • DecorView绘制流程
  • Android消息机制源码解析
  • Activity启动流程
  • Butterknife框架源码解析
  • 我之存在,因为有你
  • 霍华德*舒尔茨
  • Android相机
  • Camera
  • 悬浮窗
  • WindowManager

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • 风光摄影
  • 星空摄影
  • 人像摄影
  • 学习站点