Ubuntu 12.04 搭建ndk编译环境
搭建ndk环境之前,请保证你能新建android项目并能在手机上正常运行 通过AS自动生成ndk环境更新AS到较新的版本,通过File-setting-Androd SDK下载sdktools(这里不需要启动manager界面) 然而,实际运行总那么不尽人意。下面讲讲本人在配置环境是遇到的坑。 坑1:cmake 3.6.3155560 报错,GLIBCXX_2.4.18 required by cmake $ alien ***.rpm 但在没root权限的linux中,就算将alien安装成功,执行alien 转换 rpm安装包也会失败,非root用户不能转换文件格式。 直接使用ndk build坑2:将java文件生成h头文件失败
.h文件生成后,就开始写C(/C++)代码了 此时,你已经能得到一个h文件,里面包含了你声明的public native method(只是看起来怪怪的,仔细看你就能看懂了)。 /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_lintan_jniapplication_JniJava */ #ifndef _Included_com_lintan_jniapplication_JniJava #define _Included_com_lintan_jniapplication_JniJava #ifdef __cplusplus extern "C" { #endif /* * Class: com_lintan_jniapplication_JniJava * Method: max * Signature: (II)I */ JNIEXPORT jint JNICALL Java_com_lintan_jniapplication_JniJava_max (JNIEnv *,jobject,jint,jint); /* * Class: com_lintan_jniapplication_JniJava * Method: strFromJni * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_lintan_jniapplication_JniJava_strFromJni (JNIEnv *,jobject); #ifdef __cplusplus } #endif #endif 第15行末尾就是你的method名字,com开始就是你的包名类名等 package com.lintan.jniapplication; /** * Created by **** on 11/5/16. */ public class JniJava { /** * 返回两个整数中较大的一个 */ public native int max(int a,int b); /** * 看看熟悉的Hello World */ public native String strFromJni(); } 此时,你需要创建一个jni(cpp 也行)的文件夹,路径为”src/main/jni” // // Created by **** on 11/5/16. // #include <jni.h> #include "com_lintan_jniapplication_JniJava.h" JNIEXPORT jint JNICALL Java_com_lintan_jniapplication_JniJava_max (JNIEnv * env,jobject obj,jint a,jint b) { return (a > b) ? a : b; } JNIEXPORT jstring JNICALL Java_com_lintan_jniapplication_JniJava_strFromJni (JNIEnv * env,jobject obj) { return env->NewStringUTF("Hello World"); 到这一步,代码写完了,怎么才能让java调用到这个max方法呢? 干货内容 #以下两行代码必须,call my-dir 将返回Android.mk所在的目录 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # native这个单词要记住了,你以后添加的就是这个库 LOCAL_MODULE := "native" # hello 这个是一个名字,可以随便起一个,此行代码也可以不要,注释而已 LOCAL_PACKAGE_NAME := hello #这个就是C(CPP)文件了,里面是你的native方法的实现 LOCAL_SRC_FILES := CalculateTest.cpp # 编译成共享库 include $(BUILD_SHARED_LIBRARY) 此时还没完,因为只告诉了需要编译,要编译出那些平台的呢,因此还需要在新建一个Application.mk的文件,编译出多个平台的so #注意字别写错了,平台之间用空格隔开。 #就算ndk-build 没报错,在点击AS的Build是会报错, #错误内容,大概是就setup.mk 说PROJECT_PATH NULL,这里注意。 #笔者当时将x86_64敲成了x86_62。。。 APP_ABI := x86_64 armeabi armeabi-v7a arm64-v8a x86 mips 然后ndk-build,成功后,你会发现在你的IDE工程窗口多一个libs目录,且里面就是你编译出来的so依赖库 好了,你可以用你的native方法了,笔者使用native方法的代码为: static { //加载你的so //libs文件夹下的so名字是添加了前缀的,不用管。 System.loadLibrary("native"); } // 这是包含native方法的类 JniJava jniJava = new JniJava(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView tv = (TextView) findViewById(R.id.test); //调用max方法 String txt = jniJava.strFromJni() + " from Jni !"; tv.setText(txt); } 保险起见,还是在app的build.gradle文件(不是project的build.gradle)里添加依赖 compile fileTree(dir: 'libs',include: ['*.jar','**/*.so']) 此时,你可以尝试AS的build,没问题。 找不到这个so,哦,AS在Run的时候,还是已gradle的方式编译+run,那么,我们ndk编译出来的so不认识吗? 因此要告诉gradle(在app build.gradle)defaultConfig下添加如下代码 ndk{ moduleName "native" abiFilters("x86","x86_64","armeabi","armeabi-v7a","arm64-v8a","mips","mips64") } 到此,点击AS的熟悉Run绿色三角形箭头,success ! 如果有讲得不对的地方,欢迎大家提出来,共同学习, 谢谢! (编辑:台州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |