目录
前言
正文
修改点,举个例子
不同点
hello.c文件后缀改为hello.cpp,还有就是C++传入的参数更少,看起来更简洁。
hello.c
JNIEXPORT jstring JNICALL Java_com_biumall_jni_one_Hello_hello (JNIEnv * env , jclass jclazz){ return (*env)->NewStringUTF(env, "Hello World !---from JNI"); };
hello.cpp
JNIEXPORT jstring JNICALL Java_com_biumall_jni_one_Hello_hello (JNIEnv * env , jclass jclazz){ return env->NewStringUTF("Hello World !---from JNI"); };
Android.mk
下面有注释不同点
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_LDLIBS := -llog LOCAL_MODULE := Hello # C语言 LOCAL_SRC_FILES := Hello.c # C++ LOCAL_SRC_FILES := Hello.cpp include $(BUILD_SHARED_LIBRARY)
C++版
代码跟《》一样。只不过这里是C++版的。
PS :这里只是代码,具体动态注册流程请看《》
Hello.java
public class Hello { private final String TAG = "from_dynamic_java_"; //1. load Hello.so static { System.loadLibrary("Hello"); } // 2. define native computer() public static native int computer(String type, int a, int b); public int add(int x, int y) { return x + y; } public int sub(int x, int y) { return x - y; } }
Log.h
#include <android/log.h> //定义TAG日志打印 #define LOG_TAG "from_dynamic_jni_" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
JNICommon.h
#include <jni.h> //获取数组大小 #define ARRAY_LENGTH(x) ((int)(sizeof(x) / sizeof((x)[0]))) //注册本地方法 int registerNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods, int methods_size) { jclass clazz = env->FindClass(className); if (!clazz) { return JNI_ERR; } int result = env->RegisterNatives(clazz, methods, methods_size); if (result < 0) { return JNI_ERR; } return JNI_OK; }
Hello.cpp
#include "JNICommon.h" #include "Log.h" #include<string.h> /** * ---------------------------第一步 start --------------------------- * 定义Hello.java类路径[包名+类名,只不过.换成了/] * 包名+类名:com.biumall.dynamic.one.Hello */ #define DYNAMIC_CLASS "com/biumall/dynamic/one/Hello" /** * ---------------------------第一步 end --------------------------- */ /** * ---------------------------第二步 start --------------------------- * c_add()用于调用Java方法 * @param env env * @param jclazz jclazz * @param x x * @param y y * @return */ int c_add(JNIEnv *env, jclass jclazz, int x, int y) { jmethodID methodID = env->GetMethodID(jclazz, "add", "(II)I"); jobject object = env->AllocObject(jclazz); return env->CallIntMethod(object, methodID, x, y); } /** * c_sub()用于调用Java方法 * @param env env * @param jclazz jclazz * @param x x * @param y y * @return */ int c_sub(JNIEnv *env, jclass jclazz, int x, int y) { jmethodID methodID = env->GetMethodID(jclazz, "sub", "(II)I"); jobject object = env->AllocObject(jclazz); return env->CallIntMethod(object, methodID, x, y); } /** * 本地方法computer实现 */ JNIEXPORT jint JNICALL native_computer(JNIEnv *env, jclass jclazz, jstring type, jint a, jint b) { const char *charType = env->GetStringUTFChars(type, 0); LOGD("native_computer : %s ", charType); int count; if (!strcmp(charType, "-")) { count = c_sub(env, jclazz, a, b); } else if (!strcmp(charType, "+")) { count = c_add(env, jclazz, a, b); } env->ReleaseStringUTFChars(type, charType); return count; } /** * ---------------------------第二步 end --------------------------- */ /** * ---------------------------第三步 start --------------------------- * 定义Java和JNI函数的绑定表 * 方法数组,分别为:(native方法 , 方法签名 , 函数指针[JNI中需要实现的方法名]) * 通过javac和javap 获取 方法签名 */ JNINativeMethod method_table[] = { {"computer", "(Ljava/lang/String;II)I", (void *) native_computer}, }; /** * ---------------------------第三步 end --------------------------- */ /** * ---------------------------第四步 start --------------------------- * 注册本地方法 */ JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved ){ JNIEnv *env = NULL; int result = vm->GetEnv((void **) &env, JNI_VERSION_1_6); LOGD("JNI_OnLoad 1 result : %d", result); if(result != JNI_OK){ return JNI_ERR; } result = registerNativeMethods(env, DYNAMIC_CLASS, method_table, ARRAY_LENGTH(method_table)); LOGD("JNI_OnLoad 2 result : %d", result); if(result != JNI_OK){ return JNI_ERR; } return JNI_VERSION_1_6; } /** * ---------------------------第四步 end --------------------------- */
Application.mk
APP_ABI := arm64-v8a
Android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_LDLIBS := -llog LOCAL_MODULE := Hello LOCAL_SRC_FILES := Hello.cpp include $(BUILD_SHARED_LIBRARY)
参考文章
-
《》
-
《
历史上的今天
暂无评论...
随机推荐
毕淑敏:提醒幸福
我们从小就习惯了在提醒中过日子。天气刚有一丝风吹草动,妈妈就说,别忘了多穿衣服。才相识了一个朋友,爸爸就说,小心他是个骗子。你取得了一点成功,还没容得乐出声来,所有关切着你的人一起说,别骄傲!你沉浸在欢快中的时候,自己不停地对自己说:“千万不可太高兴,苦难也许马上就要降临……”我们已经习惯了在提醒中...
Visual Studio 2017常用部分快捷键
前言最近在使用VS2017温习C语言,这工具很多快捷键都忘了,这里记录部分,方便自己查阅,后续慢慢添加。正文1、代码片段多行注释step1、选中要注释的代码段;step2、按 Ctrl + K 键;step3、再按 Ctrl +C 键。2、代码片段取消注释step1、选中要取消注释的...
Kotlin的基本语法2
前言记录一下Kotlin基本语法2,主要涉及选择结构语句,循环结构语句和区间等,记录于此,方便自己查阅。正文选择结构语句选择结构语句分为if条件语句和when条件语句。if条件语句if条件语句分为3种语法格式。if语句if语句是指如果满足某种条件,则进行该条件下的某种处理。var...
Android Studio快捷键记录
在使用编译器时,很多人喜欢改变编译器的一些快捷键以便适应以前的习惯(以前我也是这样,后来发现换电脑或者环境后得耗时间重新配置,麻烦),但个人觉得不太好.如果编译器崩溃了或者换电脑了,您又得重新设置一遍...当然,萝卜青菜,各有所爱.只要自己喜欢怎样折腾都是好的!当然,Android Studio...
郁达夫:北平的四季
对于一个已经化为异物的故人,追怀起来,总要先想到他或她的好处;随后再慢慢的想想,则觉得当时所感到的一切坏处,也会变作很可寻味的一些纪念,在回忆里开花。关于一个曾经住过的旧地,觉得此生再也不会第二次去长住了,身处入了远离的一角,向这方向的云天遥望一下,回想起来的,自然也同样地只是它的好处。中国的大都...
利用signapk.jar工具对apk文件进行签名
什么是signapk.jarsignapk.jar是Android源码包中的一个签名工具。signapk.jar源码Android源码目录下,可以编译build/tools/signapk/生成signapk.jar。如何生成signapk.jar# 编译signapkmmm /bui...