Android JNI 手把手教你编写.so并调用接口

来源:互联网 发布:淘宝如何加入全球购 编辑:程序博客网 时间:2024/06/06 00:35

最近在看了很多JNI资料,用了各种方法,但个人却喜欢这种方式,废话不多说。


一、在android源码package目录下创建一个文件夹TestJni,并创建两个目录,分别为test_jni.cpp和Android.mk


二、编写test_jni.cpp:

#include <stdio.h>    
#include <errno.h>    
#include <fcntl.h>    
#include <unistd.h>    
#include <stdint.h>    
#include <assert.h>    
//#include <cutils/log.h>    
#include <string.h>    
#include <jni.h>    
#include "android_runtime/AndroidRuntime.h"
     
static const char *kClassName = "com/example/test_jni/testjni";  //需要注册的类,注意我的是testjni.java

jint openportNative(JNIEnv *env,jobject obj,int state)
{
//printf("+++++++OpenPort++++++++\n");
state = 111;
return state;
}
jint closeportNative(JNIEnv *env,jobject obj,int state)
{
//printf("+++++++ClosePort++++++++\n");
state = 222;
return state;
}

static JNINativeMethod gMethods[] = {    
    /* name, signature, funcPtr */    
    {"openport",    "(I)I",                   (void*)openportNative}, //绑定 ,openport为java应用层的接口,对应JNI openportNative接口;
    {"closeport",    "(I)I",                (void*)closeportNative}    
};    

jint JNI_OnLoad(JavaVM *vm, void *reserved)    //这个很重要,详细说明不解散;
{    
    JNIEnv *env = NULL;    
    jclass cls;
    jint result = -1;    
     
    if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {    
       
        return -1;    
    }    
    cls = env->FindClass((const char*)kClassName);    
    if (cls == NULL) {          
        return -1;    
    }    
    if (env->RegisterNatives( cls, gMethods, sizeof(gMethods)/sizeof(gMethods[0])) < 0) {    
      
        return -1;    
    }    
result=JNI_VERSION_1_4;
    return result;    
}    

三、编写Android.mk文件:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
LOCAL_SRC_FILES:= test_jni.cpp  
LOCAL_C_INCLUDES += \
    $(JNI_H_INCLUDE) 
LOCAL_SHARED_LIBRARIES := \
    libandroid_runtime     
LOCAL_MODULE := libtest_jni
LOCAL_MODULE_TAGS := eng
include $(BUILD_SHARED_LIBRARY)

四、执行source build/envsetup.sh---->lunch xxx -----> make test_jni -j4

编译完成后.so文件将直接保存到out/target/product/xxxxx/system/lib/目录下,将他拷贝到eclipse的libs目录下即可,接下来我们调用下接口;


五、MainActivity.java  代码很简单,新建两个按钮,然后访问库文件的接口,并接受返回值,数值确认是正确的。

package com.example.test_jni;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import com.example.testjni.R;
import com.example.test_jni.testjni;

public class MainActivity extends Activity {
    private Button btn1,btn2;
    int red;
    static {                   
        System.loadLibrary("test_jni");                    //静态加载库
        }                                           
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
      
        final testjni j = new testjni();            //创建一个对象,这个对象看下面的代码,里面有包含native方法
        btn1 = (Button)findViewById(R.id.bt1);
        btn2 = (Button)findViewById(R.id.bt2);
        btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
               red = j.openport(111);   //执行native openport方法
               System.out.println("red========="+red);              
            }                   
        });
        btn2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                red =j.closeport(222); //同上
                System.out.println("red========="+red);              
            }
        });
              
    }
}

六、testjni.java类

package com.example.test_jni;

public class testjni {
    static {                   
        System.loadLibrary("test_jni");                    
        }                                         
    public native int openport(int a);  //本地方法  
    public native int closeport(int b);
}

七、在eclipse编译成APK文件,安装APK。



0 0