前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >简单的NDK开发

简单的NDK开发

作者头像
NaOH
发布2018-05-29 11:33:58
6510
发布2018-05-29 11:33:58
举报
配置NDK环境,进行简单Native开发
NDK下载
环境变量配置

为ndk和jdk配置环境目录保证javah命令和ndk-build命令可以直接在命令行使用。

为AndroidStudio工程配置NDK路径

打开local.properties文件,添加ndk目录:

代码语言:javascript
复制
sdk.dir=C\:\\Users\\realhe\\AppData\\Local\\Android\\Sdk
ndk.dir=D\:\\ndk\\android-ndk-r10c

打开build.gradle,在defaultConfig中添加ndk{}:

代码语言:javascript
复制
android {
    compileSdkVersion 24
    buildToolsVersion "24.0.0"

    defaultConfig {
        applicationId "com.example.realhe.myapplication"
        minSdkVersion 19
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
      //配置处如下
        ndk{
            moduleName "test"            //生成的so名字
            abiFilters "armeabi", "armeabi-v7a", "x86"    //输出指定三种abi体系结构下的so库
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        //此处为调试配置,可选项
            ndk {
                debuggable = true
            }
        }
        debug {
            debuggable = true
        //此处为调试配置,可选项
            jniDebuggable = true
        }
    }

}

保存后可能发生

NDK integration is deprecated in the current plugin. Consider trying the new experimental plugin

解决方法为在gradle.properties 中添加一行:

代码语言:javascript
复制
android.useDeprecatedNdk=true
JNI初步
创建文件夹

new > Folder >JNI Folder创建jni文件夹,默认目录为

app/src/main/jni

新建一个使用jni的类
代码语言:javascript
复制
public class Test {
    static {
        System.loadLibrary("test");//需要与前面的so文件名保持一致
    }
    public native String get();
    public native void set(String str);
    public native int getToken(int token);
}
导出Test类的native方法对应的头文件:
代码语言:javascript
复制
C:\Users\realhe\AndroidStudioProjects\MyApplication>
javah -classpath 
app\build\intermediates\classes\debug\ 
-d 
app\src\main\jni 
com.example.realhe.myapplication.Test

上面参数的含义依次是javah命令,classpath路径

.class文件所在的文件夹app\build\intermediates\classes\debug\

-d:输出.h到目标文件夹app\src\main\jni (即前面我们制定的默认jni文件夹)

com.example.realhe.myapplication.Test:含有native方法的类

注意这个地方一定要在项目根目录下使用,而不能切换到 Test类的.class文件所在目录直接使用

之后可以看到生成的头文件:

代码语言:javascript
复制
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_realhe_myapplication_Test */

#ifndef _Included_com_example_realhe_myapplication_Test
#define _Included_com_example_realhe_myapplication_Test
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_realhe_myapplication_Test
 * Method:    get
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_realhe_myapplication_Test_get
  (JNIEnv *, jobject);

/*
 * Class:     com_example_realhe_myapplication_Test
 * Method:    set
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_example_realhe_myapplication_Test_set
  (JNIEnv *, jobject, jstring);

/*
 * Class:     com_example_realhe_myapplication_Test
 * Method:    getToken
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_example_realhe_myapplication_Test_getToken
  (JNIEnv *, jobject, jint);

#ifdef __cplusplus
}
#endif
#endif
实现头文件中的方法

在默认的JNI文件夹中新建一个test.c文件,包含上述头文件并实现其中的方法:

代码语言:javascript
复制
//
// Created by realhe on 2016/7/18.
//
#include "com_example_realhe_myapplication_Test.h"
static int count = 0;
JNIEXPORT jstring JNICALL Java_com_example_realhe_myapplication_Test_get
        (JNIEnv *env, jobject obj){
return (*env)->NewStringUTF(env,"This is a test for NDK!");
}

/*
 * Class:     com_example_realhe_myapplication_Test
 * Method:    set
 * Signature: (Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_com_example_realhe_myapplication_Test_set
(JNIEnv *env, jobject ibj, jstring jsr){}

/*
 * Class:     com_example_realhe_myapplication_Test
 * Method:    getToken
 * Signature: (I)I
 */
JNIEXPORT jint JNICALL Java_com_example_realhe_myapplication_Test_getToken
        (JNIEnv *env, jobject obj, jint jinvar){
    return count++;
}

注意:此处由于ndk的一个BUG,在编译单个.c文件时会报错:

com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command 'D:ndkandroid-ndk-r10ndk-build.cmd'' finished with non-zero exit value 2

解决方法为在同级目录下增加一个empty.c的空文件即可。

使用Native方法

在MainActivity中使用Nativce方法设置TextViewText:

代码语言:javascript
复制
TextView textView = (TextView)findViewById(R.id.tv_hello);
Test test = new Test();
String content = test.get();
for (int i = 0;i<10;i++){
  content += ("\n("+ test.getToken(1) + ")");
}
textView.setText(content);

最后效果如下:

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016年08月15日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 配置NDK环境,进行简单Native开发
    • NDK下载
      • 环境变量配置
        • 为AndroidStudio工程配置NDK路径
          • JNI初步
            • 创建文件夹
            • 新建一个使用jni的类
            • 导出Test类的native方法对应的头文件:
            • 实现头文件中的方法
          • 使用Native方法
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档