如何在Android下使用JNI

 我来答
匿名用户
2017-03-26
展开全部
第一步: 使用Java编写HelloWorld 的Android应用程序: package com.lucyfyr; import android.app.Activity; import android.os.Bundle; import android.util.Log; public class HelloWorld extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   setContentView(R.layout.main);   Log.v("dufresne", printJNI("I am HelloWorld Activity")); }   static   {     //加载库文件     System.loadLibrary("HelloWorldJni");   }   //声明原生函数 参数为String类型 返回类型为String   private native String printJNI(String inputStr); }   这一步我们可以使用eclipse来生成一个App; 因为eclipse会自动为我们编译此Java文件,后面要是用到。 第二步:   生成共享库的头文件:   进入到eclipse生成的Android Project中 :/HelloWorld/bin/classes/com/lucyfyr/ 下:   可以看到里面后很多后缀为.class的文件,就是eclipse为我们自动编译好了的java文件,其中就有:     HelloWorld.class文件。   退回到classes一级目录:/HelloWorld/bin/classes/ 执行如下命令:   javah com.lucyfyr.HelloWorld   生成文件:com_lucyfyr_HelloWorld.h /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_lucyfyr_HelloWorld */ #ifndef _Included_com_lucyfyr_HelloWorld #define _Included_com_lucyfyr_HelloWorld #ifdef __cplusplus extern "C" { #endif /* * Class: com_lucyfyr_HelloWorld * Method: printJNI * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_lucyfyr_HelloWorld_printJNI (JNIEnv *, jobject, jstring); #ifdef __cplusplus } #endif #endif   可以看到自动生成对应的函数:Java_com_lucyfyr_HelloWorld_printJNI     Java_ + 包名(com.lucyfyr) + 类名(HelloWorld) + 接口名(printJNI):必须要按此JNI规范来操作;   java虚拟机就可以在com.simon.HelloWorld类调用printJNI接口的时候自动找到这个C实现的Native函数调用。   当然函数名太长,可以在.c文件中通过函数名映射表来实现简化。 第三步: 实现JNI原生函数源文件: 新建com_lucyfyr_HelloWorld.c文件: #include <jni.h> #define LOG_TAG "HelloWorld" #include <utils/Log.h> /* Native interface, it will be call in java code */ JNIEXPORT jstring JNICALL Java_com_lucyfyr_HelloWorld_printJNI(JNIEnv *env, jobject obj,jstring inputStr) {   LOGI("dufresne Hello World From libhelloworld.so!");   // 从 instring 字符串取得指向字符串 UTF 编码的指针   const char *str =   (const char *)(*env)->GetStringUTFChars( env,inputStr, JNI_FALSE );   LOGI("dufresne--->%s",(const char *)str);   // 通知虚拟机本地代码不再需要通过 str 访问 Java 字符串。   (*env)->ReleaseStringUTFChars(env, inputStr, (const char *)str );   return (*env)->NewStringUTF(env, "Hello World! I am Native interface"); } /* This function will be call when the library first be load. * You can do some init in the libray. return which version jni it support. */ jint JNI_OnLoad(JavaVM* vm, void* reserved) {   void *venv;   LOGI("dufresne----->JNI_OnLoad!");   if ((*vm)->GetEnv(vm, (void**)&venv, JNI_VERSION_1_4) != JNI_OK) {     LOGE("dufresne--->ERROR: GetEnv failed");     return -1;   }   return JNI_VERSION_1_4; }   OnLoadJava_com_lucyfyr_HelloWorld_printJNI 函数里面做一些log输出 注意JNI中的log输出的不同。   JNI_OnLoad函数JNI规范定义的,当共享库第一次被加载的时候会被回调, 这个函数里面可以进行一些初始化工作,比如注册函数映射表,缓存一些变量等, 最后返回当前环境所支持的JNI环境。本例只是简单的返回当前JNI环境。 第四步: 编译生成so库   编译com_lucyfyr_HelloWorld.c成so库可以和app一起编译,也可以都单独编译。 在当前目录下建立jni文件夹:HelloWorld/jni/   下建立Android.mk ,并将com_lucyfyr_HelloWorld.c和 com_lucyfyr_HelloWorld.h 拷贝到进去 编写编译生成so库的Android.mk文件: LOCAL_PATH:= $(call my-dir) # 一个完整模块编译 include $(CLEAR_VARS) LOCAL_SRC_FILES:=com_lucyfyr_HelloWorld.c LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) LOCAL_MODULE := libHelloWorldJni LOCAL_SHARED_LIBRARIES := libutils LOCAL_PRELINK_MODULE := false LOCAL_MODULE_TAGS :=optional include $(BUILD_SHARED_LIBRARY) 系统变量解析:   LOCAL_PATH - 编译时的目录   $(call 目录,目录….) 目录引入操作符     如该目录下有个文件夹名称 src,则可以这样写 $(call src),那么就会得到 src 目录的完整路径   include $(CLEAR_VARS) -清除之前的一些系统变量   LOCAL_MODULE - 编译生成的目标对象   LOCAL_SRC_FILES - 编译的源文件   LOCAL_C_INCLUDES - 需要包含的头文件目录   LOCAL_SHARED_LIBRARIES - 链接时需要的外部库   LOCAL_PRELINK_MODULE - 是否需要prelink处理   include$(BUILD_SHARED_LIBRARY) - 指明要编译成动态库
Storm代理
2023-07-25 广告
StormProxies是一家可靠的代理服务提供商,提供原生IP(住宅原生IP)和高匿名代理服务。以下是关于StormProxies的原生IP服务的一些信息:1. 住宅原生IP:StormProxies提供的住宅原生IP是指从真实的家庭或企... 点击进入详情页
本回答由Storm代理提供
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式