Showing posts with label JNI. Show all posts
Showing posts with label JNI. Show all posts

Oct 23, 2010

Android通过JNI调用native code

0.  用Eclipse 创建 Android Project
1. 创建Java类,这个类的作用是描述native code中的函数, 比如DemoLib
2. 生成native code头文件, javah -jni ...
3. 实现native code
4. 编写jni/Android.mk
5. 编译native code, 生成动态库
6. 在Java程序中调用native code
7. 测试

0. 先通过 Eclipse 创建一个Android Project
Project name: LibDemoTest
Build Target: Android 2.2
Package name: org.ox0spy.libdemotest
Create Activity: LibDemoTest

1. 在src中添加一个新类 - DemoLib
Package: org.ox0spy.libdemotest
Name: DemoLib

DemoLib.java 内容如下:
package org.ox0spy.libdemotest;

public class DemoLib {
    static {
        System.loadLibrary("demo");
    }  
   
    public native int multiply(int a, int b);
   
    public native String greet();
}

注意: 编辑完了一定保存下.

2. 生成native code的头文件
$ cd ~/workspace/LibDemoTest/bin
$ javah -jni org.ox0spy.libdemotest.DemoLib

$ mkdir ../jni
$ mv org_ox0spy_libdemotest_DemoLib.h ../jni/

3. 实现native code, demo.c 内容如下:
#include "org_ox0spy_libdemotest_DemoLib.h"


JNIEXPORT jint JNICALL Java_org_ox0spy_libdemotest_DemoLib_multiply
  (JNIEnv * env, jobject obj, jint a, jint b)
{
    return a*b;
}

JNIEXPORT jstring JNICALL Java_org_ox0spy_libdemotest_DemoLib_greet
  (JNIEnv * env, jobject obj)
{
    return (*env)->NewStringUTF(env, "Hello Android!");
}

4. 编写jni/Android.mk
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_SRC_FILES := demo.c
LOCAL_MODULE    := demo

include $(BUILD_SHARED_LIBRARY)

5. 编译native code
$ cd ~/workspace/LibDemoTest
$ ndk-build   # 先将android-ndk-r4b加入你的PATH中

6. Java程序中调用native code, 我在LibDemoTest.java中用到了native code
LibDemoTest内容如下:
package org.ox0spy.libdemotest;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class LibDemoTest extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        DemoLib demoLib = new DemoLib();

        int result = demoLib.multiply(100, 100);
        String str = demoLib.greet();

        TextView tv = new TextView(this);
        tv.setText(str + "\n" + Integer.toString(result));

        setContentView(tv);
    }
}

7. 测试, Eclipse, Run -> Run

我碰到的错误:
No implementation found for native

碰到这个错误时,我是用System.load("demo")加载动态库的,而且从logcat的输出发现libdemo.so已经成功加载了。
我是因为一开始没有用javah -jni 生成头文件,自己写的native code函数声明是:
jint multiply(jint a, jint b);

所以, 只要用javah -jni 生成头文件应该就不会碰到这个问题了.