eclipse的JNI学习

来源:互联网 发布:霍金人工智能开场白 编辑:程序博客网 时间:2024/05/31 19:23




Android上层的Application和ApplicationFramework都是使用Java编写,底层包括系统和使用众多的LIiraries都是C/C++编写的。所以上层Java要调用底层的C/C++函数库必须通过Java的JNI来实现。


普通.os文件使用方法:

1、在你的项目根目录下建立libs/armeabi目录;

2、将libxxx.so文件copy到 libs/armeabi/下;

3、此时ADT插件自动编译输出的.apk文件中已经包括.so文件了;

4、安装APK文件,即可直接使用JNI中的方法;

我想还需要简单说明一下libxxx.so的命名规则,沿袭Linux传统,lib<something>.so是类库文件名称的格式,但在Java的System.loadLibrary(“ something ”)方法中指定库名称时,不能包括 前缀—— lib,以及后缀——.so。

完成自己的jni编程并生成.os文件

JNI是Java平台定义的用于和宿主平台上的本地代码进行交互的“Java标准”,它通常有两个使用场景:1.使用(之前使用c/c++、delphi开发的)遗留代码;2.为了更好、更直接地与硬件交互并 获得更高性能 。

1、首先配置NDK开发环境,下载android-ndk-r10b工具并解压(这个网上很好找记录解压后的位置,打开eclipse软件,在工具栏选择windows-->preferences,打开如下窗口,选择android-->NDK-->NDK Location,选择browse,选择刚刚解压android-ndk-r10b的文件根目录位置。


2、新建一个android工程,起名为JniTest,MainActivity所在包名为:com.example.jnitest;在src文件夹下添加一个新的package,命名为com.example.jni,在该package下添加一个java文件,该文件用于存储我们新建的jni方法。文件格式如下:

TestJni.java的的代码,这里共定义了四个方法:

package com.example.jni;

public class TestJni {

public native boolean init();
public native int add(int x , int y);
public native void destory();
public native String getString();

}

3、通过javah命令生成所需的.h文件;保存上面的工程,并文件夹打开工程项目根目录,此时可以查看是否存在class文件,位置在bin-->classes-->com-->example-->jni-->TestJni,如果不存在,请重新build project并继续下面步骤:返回根目录-->bin-->classes文件夹下,此时该文件夹下只有一个com文件。shift+右击,选择在此处打开命令窗口,如果没有该项,通过com命令,定位到该位置也可以。打开命令提示符窗口,输入:javah com.example.jni.TestJni


则会在根目录-->bin-->classes文件下生成一个com_example_jni_TestJni.h的文件。该文件即是我们需要的头文件。内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_jni_TestJni */


#ifndef _Included_com_example_jni_TestJni
#define _Included_com_example_jni_TestJni
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_example_jni_TestJni
 * Method:    init
 * Signature: ()Z
 */
JNIEXPORT jboolean JNICALL Java_com_example_jni_TestJni_init
  (JNIEnv *, jobject);


/*
 * Class:     com_example_jni_TestJni
 * Method:    add
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_example_jni_TestJni_add
  (JNIEnv *, jobject, jint, jint);


/*
 * Class:     com_example_jni_TestJni
 * Method:    destory
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_example_jni_TestJni_destory
  (JNIEnv *, jobject);


/*
 * Class:     com_example_jni_TestJni
 * Method:    getString
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_example_jni_TestJni_getString
  (JNIEnv *, jobject);


#ifdef __cplusplus
}
#endif
#endif

4、右击工程“JniTest”,选择android Tools-->add native support,给添加的lib命名为JniTest,注意,此时命名默认带有前缀lib和后缀.so,点击finish结束。


此时,原工程根目录下会增加了一个jni文件夹,将3步骤生成的com_example_jni_TestJni.h头文件复制到该jni文件夹下,并添加以下文件
com_example_jni_TestJni.cpp,源码:
#include <stdio.h>
#include <stdlib.h>
#include "com_example_jni_TestJni.h"
#include "Add.h"
CAdd *pCAdd = NULL;
JNIEXPORT jboolean JNICALL Java_com_example_jni_TestJni_init(JNIEnv *env,jobject obj) {
   if (pCAdd == NULL) {
        pCAdd = new CAdd;
    }
   return pCAdd != NULL;
}
JNIEXPORT jint JNICALL Java_com_example_jni_TestJni_add(JNIEnv *env, jobject obj,
        jint x, jint y) {
        int res = -1;
       if (pCAdd != NULL) {
          res = pCAdd->Add(x, y);
        }
       return res;
}
JNIEXPORT void JNICALL Java_com_example_jni_TestJni_destory(JNIEnv *env, jobject obj)
{    if (pCAdd != NULL)
    {
        pCAdd = NULL;
    }
}
JNIEXPORT jstring JNICALL Java_com_example_jni_TestJni_getString(JNIEnv *env, jobject obj){


return env->NewStringUTF("HELLO JNI!!");
}
Add.cpp文件源码:
 #include "Add.h"
 CAdd::CAdd() {
 }
 CAdd::~CAdd() {
 }
 int CAdd::Add(int x, int y) {    
 return x + y;
}
Add.h文件源码:
#ifndef _TEST_JNI_ADD_H_
 #define _TEST_JNI_ADD_H_
    class CAdd {public:
         CAdd();    
        ~CAdd();    
        int Add(int x, int y);
    };
#endif
修改Android.mk文件内容为:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := JniTest
LOCAL_SRC_FILES := com_example_jni_TestJni.cpp
LOCAL_SRC_FILES += Add.cpp
include $(BUILD_SHARED_LIBRARY)


此时应该会报错,解决办法:右击工程名,选择Properties,打开Properties for JniTest,选择C/C++ General-->Paths and Symbols-->includes-->add-->File system,选择android-ndk-r10b的文件解压路径,然后依次选择android-ndk-r10b-->platforms-->android-?(选择对应的android target版本)-->arch-arm-->usr-->include,点击确定添加。此时clean并rebuild project,错误消失。此时会在libs文件夹下生成一个armeabi文件夹,打开armeabi,里面就有我们需要的libTestJni.os文件。


5、在我们新建的TestJni.java文件中添加以下代码:

static{
System.loadLibrary("JniTest");
}

在MainActivity.java中修改以下代码:


public class MainActivity extends Activity {

TextView tvX = null;
TextView tvY = null;
TextView tvSum = null; 
Button   btnAdd = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);
tvX = (TextView)findViewById(R.id.et_x);
tvY = (TextView)findViewById(R.id.et_y);
tvSum = (TextView)findViewById(R.id.et_sum);
btnAdd = (Button)findViewById(R.id.btn_add);
btnAdd.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) { 
int x = Integer.valueOf( tvX.getText().toString());
int y = Integer.valueOf( tvY.getText().toString());
int sum = 0;
TestJni jni = new TestJni();
boolean flag = jni.init();
if(flag){
sum = jni.add(x, y);
}
btnAdd.setText(String.valueOf(sum));

jni.destory();
tvSum.setText(String.valueOf(jni.getString()));
}
});

}

}


此时就是通过调用TestJni中的方法使用C和C++进行计算。试一下结果:


点击button后:


我们的jni初步学习到此为止!


0 0
原创粉丝点击