Ndk基础知识(二)Ndk基本使用流程
2018-01-24 16:32
369 查看
本篇博文基于前一篇Ndk基础知识(一)环境搭建编写,有需要的读者请先阅读前一篇博文。
对应的c++方法命名为对应的返回类型+类的全名(包名+类名,其中将”.”换成”_”)+方法名+(JNIEnv *env, jobject thiz + 参数)如:
生成java方法对应的c层的方法名看起来比较复杂,其实也有对应的工具可以使用,java提供了javah可以自动生成java native方法对应的c头文件。
在Android Studio中可以设置该命令。操作如下:File->Settings->Tools->External Tools中选择加号添加一个工具,在该窗口中进行如下设置
设置完成后,我们看如何使用:
首先写好java类,Build->Make Project生成相关类文件,这一步很重要,javah是根据class 文件去生成头文件的,所以必须先生成相应的class文件。然后对该类右键选择External Tools->javah生成相应的头文件,按照当前配置,生成的头文件会放在jni目录中。事实上得到头文件后放在哪个位置可根据需要自己重新剪切调整,甚至不使用头文件直接把该方法声明拿去使用也是可以的,javah命令只是方便我们不用去写容易出错的方法名罢了。
Build->Make Project,生成class文件,右键External Tools->javah生成对应的头文件,在native-lib.cpp文件中实现上述方法。
在MainActivity中调用:
上述内容介绍了简单数据类型和字符串在c和java之间的传递。其中jint,jstring,jintArray是java中的int,String,int[]在c中对应类型,这些内容定义在jni.h中。下面列出c和java中部分类型的对应关系:
预备知识
在AndroidStudio自动生成的项目中,我们猜想stringFromJNI()和cpp文件中的Java_com_breeze_ndkdemo2_MainActivity_stringFromJNI是对应的,事实上确实如此。根据JNI的命名规则,java层的native方法命名规则为在返回类型前加native,如public native String stringFromJNI();
对应的c++方法命名为对应的返回类型+类的全名(包名+类名,其中将”.”换成”_”)+方法名+(JNIEnv *env, jobject thiz + 参数)如:
jstring Java_com_breeze_ndkdemo2_MainActivity_stringFromJNI( JNIEnv *env, jobject /* this */)
生成java方法对应的c层的方法名看起来比较复杂,其实也有对应的工具可以使用,java提供了javah可以自动生成java native方法对应的c头文件。
在Android Studio中可以设置该命令。操作如下:File->Settings->Tools->External Tools中选择加号添加一个工具,在该窗口中进行如下设置
设置完成后,我们看如何使用:
首先写好java类,Build->Make Project生成相关类文件,这一步很重要,javah是根据class 文件去生成头文件的,所以必须先生成相应的class文件。然后对该类右键选择External Tools->javah生成相应的头文件,按照当前配置,生成的头文件会放在jni目录中。事实上得到头文件后放在哪个位置可根据需要自己重新剪切调整,甚至不使用头文件直接把该方法声明拿去使用也是可以的,javah命令只是方便我们不用去写容易出错的方法名罢了。
举例
新建一个NativeUtils类内容如下:public class NativeUtils { public static native int addNum(int num); public static native String addChar(String str); public static native int[] addArray(int[] arr, int length); }
Build->Make Project,生成class文件,右键External Tools->javah生成对应的头文件,在native-lib.cpp文件中实现上述方法。
#include <jni.h> #include <string> #include <android/log.h> #include <string.h> #include "com_breeze_ndkdemo2_NativeUtils.h" extern "C" jstring Java_com_breeze_ndkdemo2_MainActivity_stringFromJNI( JNIEnv *env, jobject /* this */) { std::string hello = "Hello from C++"; return env->NewStringUTF(hello.c_str()); } JNIEXPORT jint JNICALL Java_com_breeze_ndkdemo2_NativeUtils_addNum (JNIEnv *, jclass, jint num){ return num + 1; } /* * Class: com_breeze_ndkdemo2_NativeUtils * Method: addChar * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_breeze_ndkdemo2_NativeUtils_addChar (JNIEnv *env , jclass, jstring str){ jsize alen = env->GetStringLength(str); char * strs = new char[alen + 1]; jboolean isCopy = true; const jchar* chars = env->GetStringChars(str, &isCopy); for (int i = 0; i < alen; i++){ strs[i] = chars[i]; } __android_log_write(ANDROID_LOG_INFO, "str from java", strs); std::string s = "hello"; return env->NewStringUTF(s.c_str()); } /* * Class: com_breeze_ndkdemo2_NativeUtils * Method: addArray * Signature: ([I)[I */ JNIEXPORT jintArray JNICALL Java_com_breeze_ndkdemo2_NativeUtils_addArray (JNIEnv *env, jclass, jintArray array, jint length){ jboolean isCopy = true; jint* arr = env->GetIntArrayElements(array, &isCopy); for (int i = 0; i < length; i++){ arr[i] = arr[i] + 1; } jintArray javaArray; javaArray = env->NewIntArray(length); env->SetIntArrayRegion(javaArray, 0, length, arr); return javaArray; }
在MainActivity中调用:
public class MainActivity extends AppCompatActivity { // Used to load the 'native-lib' library on application startup. static { System.loadLibrary("native-lib"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Example of a call to a native method TextView tv = (TextView) findViewById(R.id.sample_text); tv.setText(stringFromJNI()); int num = NativeUtils.addNum(3); Log.d("ZXX", num + ""); String str = NativeUtils.addChar("hello"); Log.d("ZXX", str); int [] arr = NativeUtils.addArray(new int[]{1, 2, 3}, 3); for (int i = 0; i < arr.length; i++){ Log.d("ZXX", "num" + i + ":" + arr[i]); } } /** * A native method that is implemented by the 'native-lib' native library, * which is packaged with this application. */ public native String stringFromJNI(); }
上述内容介绍了简单数据类型和字符串在c和java之间的传递。其中jint,jstring,jintArray是java中的int,String,int[]在c中对应类型,这些内容定义在jni.h中。下面列出c和java中部分类型的对应关系:
Java类型 | 本地类型 | 描述 |
---|---|---|
boolean | jboolean | C/C++8位整型 |
byte | jbyte | C/C++带符号的8位整型 |
char | jchar | C/C++无符号的16位整型 |
short | jshort | C/C++带符号的16位整型 |
int | jint | C/C++带符号的32位整型 |
long | jlong | C/C++带符号的64位整型e |
float | jfloat | C/C++32位浮点型 |
double | jdouble | C/C++64位浮点型 |
Object | jobject | 任何Java对象,或者没有对应java类型的对象 |
Class | jclass | Class对象 |
String | jstring | 字符串对象 |
Object[] | jobjectArray | 任何对象的数组 |
boolean[] | jbooleanArray | 布尔型数组 |
byte[] | jbyteArray | 比特型数组 |
char[] | jcharArray | 字符型数组 |
short[] | jshortArray | 短整型数组 |
int[] | jintArray | 整型数组 |
long[] | jlongArray | 长整型数组 |
float[] | jfloatArray | 浮点型数组 |
double[] | jdoubleArray | 双浮点型数组 |
相关文章推荐
- NDK学习笔记:动态链接库与静态链接库的基本使用流程简记
- python 爬虫开发所需基础知识 - urllib库的基本使用
- java 基础知识之I/O流 其二(基本使用)
- Java基础知识强化之集合框架笔记31:集合之泛型类的概述和基本使用
- TensorFlow+Python基础知识和基本包的使用
- [ FI基本业务流程 ] - Accounts Payable基础知识
- Java 基础知识 8种基本数据类型 equal 与==区别 Switch 使用
- 【Android基础知识】AsyncTask基本使用
- Ruby基础知识之基本流程控制
- Struts2基本流程及基础知识问答
- UIScrollView的基本使用方法和注意事项 - iOS - UI基础知识总结10
- JAVA基础知识思维导图:unit01_开发环境,变量,基本类型及转换,数学运算,流程控制,数组
- 【Android基础知识】Apache HttpClient的基本使用
- java基础知识之方法的概述及基本使用
- <基础知识>github配置和基本使用
- 【Android基础知识】ViewPager基本使用
- 【Android基础知识】IntentService基本使用
- 最基本财务基础知识,财务知识基础
- JavaScript中字面量与函数的基本使用知识
- SQL Server 索引基础知识(8)--- 数据基本格式补充