android studio利用cmake实现NDK

下载安装studio, ndk, jdk这些步骤就免了。(我的环境是win7, studio 2.3.3, NDK r14, jdk1.8.0.21, gradle 2.3.3)
工具升级到最新版本总是不错的,旧版本可能不支持。所以建议版本过低的可以先升级后操作。
通过studio SDK Manager下载最新的NDK和cmake,可以免掉makefile,直接build apk便会产生so文件,直接调用。
1. 新建一个android工程(工程名HelloJni, 包名com.hubin.hellojni),在app/src/main根目录下新建jni目录
2. 在project的local.properties, 增加一行, 其实就是NDK的根目录:
   ndk.dir=E\:\\androidsdk\\studiosdk\\studiosdk\\ndk-bundle
   一般情况下,通过studio下载了NDK会自动帮你加上去,如果没有就手动添加
3. 在jni目录下新建C文件,编写c代码. 如我写了一个叫hello-jni.c, 内容如下
   #include <string.h>
   #include <jni.h>
   #include  <android/log.h>
   #define  TAG    "JNITAG"
   // 定义debug信息,其他级别的Log亦如此
   #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
   // 这就是JNI的规则,方法名必须是Java_包名_类名_方法名, 千万不要偷懒,Java的首字母一定要大些,包名之间要下划线
   JNIEXPORT jstring JNICALL
   jstring Java_com_hubin_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz )
   {
       return (*env)->NewStringUTF(env, "Hello from JNI !");
   }
   JNIEXPORT jstring JNICALL 
   Java_com_hubin_hellojni_HelloJni_stringFromJNI2( JNIEnv* env, jobject thiz )
   {
  jstring str = "what a fucking good test";
  LOGD("str=%s", str);
  return (*env)->NewStringUTF(env, "Hello from JNI2 ! ");
   }   
4. C文件写好了,在java代码写native方法:
public final class HelloJni {
private static HelloJni helloJni;
private HelloJni ()
{
System.loadLibrary("hello-jni"); //不要写成libhello-jni, studio已经帮你做好了
}
public static HelloJni getInstance()
{
if (null == helloJni)
{
helloJni = new HelloJni();
}
return helloJni;
}
public native String stringFromJNI();
public native String stringFromJNI2();
}
5. c代码和java native代码也写好了,是时候编译了,在jni目录下新建文件:CMakeLists.txt, 内容如下:
      cmake_minimum_required(VERSION 3.4.1)
      add_library(hello-jni SHARED  // so文件名
                         hello-jni.c           // 要编译的c文件,有多个就往下添加
                         hello.c)
     target_link_libraries(hello-jni
                                    android
                                    log)
6. 修改在app下的build.gradle,增加以下内容:

    apply plugin: 'com.android.application'

android {

compileSdkVersion 26
buildToolsVersion "26.0.0"
defaultConfig {
applicationId "com.hubin.hellojni"
minSdkVersion 19
targetSdkVersion 26
versionCode 1
versionName "1.0"
// 新增的jni编译部分
externalNativeBuild {
cmake {
arguments '-DANDROID_TOOLCHAIN=clang'
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
// 新增的jni编译部分
externalNativeBuild {
cmake {
path "src/main/jni/CMakeLists.txt" //编译cmake文件
}
}
// 新增的jni编译部分
productFlavors {
arm7 {
ndk {
abiFilter 'armeabi-v7a'
}
}
arm8 {
ndk {
abiFilters 'arm64-v8a'
}
}
arm {
ndk {
abiFilter 'armeabi'
}
}
x86 {
ndk {
abiFilter 'x86'
}
}
x86_64 {
ndk {
abiFilter 'x86_64'
}
}
mips {
ndk {
abiFilters 'mips', 'mips64'
}
}
universal {
ndk {
abiFilters 'mips', 'mips64', 'x86', 'x86_64'
}
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:26.+'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
testCompile 'junit:junit:4.12'
}
7. 在android中调用native方法
   public class MainActivity extends AppCompatActivity {
       private TextView jni_text;
       @Override
       protected void onCreate(Bundle savedInstanceState)
       {
           super.onCreate(savedInstanceState);
           setContentView(R.layout.activity_main);
           jni_text = (TextView) findViewById(R.id.jni_text);
           String text = HelloJni.getInstance().stringFromJNI();
           String text1 = HelloJni.getInstance().stringFromJNI2();
           jni_text.setText(text + "-" + text1);
       }
}
8. 编译运行, Build-->Clean Project
                      Build-->Build APK
   或gradlew clean
       gradlew assembleDebug 
  编译后,会在app/build/intermediates/cmake/arm7/debug/obj/armeabi-v7a目录下生成libhello-jni.so
  安装APK,运行会看到期望的结果。
9. 打印JNI日志, 在.c文件的头部加入
   #include  <android/log.h>
   #define  TAG    "JNITAG"
   // 定义debug信息,其他级别的Log亦如此
   #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
   在方法中直接调用LOGD
   jstring str = "what a fucking good test";
   LOGD("str=%s", str);
   在studio logcat窗口过滤JNITAG即可看到JNI log
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LakeSideHu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值