编写HelloWorld JNI
新建Android项目,编写一个native方法,
一个native方法是一个java调用非java代码的接口,native方法可以由c来实现
package tu.bb.ndk;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
public class MainActivity extends Activity {
//本地方法
public native String sayHello();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
用JNI协议来进行Java和C代码的相互调用、通信,Java的本地方法由C来实现,需要符合一套JNI的命名规则和数据类型的转换,我们可以借助jdk提供的 (javah 类全名) 命令来生成C语言的头文件,cd到工程目录下的src文件下,执行javah命令就会在src目录下生成一个头文件了


在工程目录下创建jni目录,拷贝刚才生成的头文件、创建Java native 方法C语言实现文件、Android.mk文件,Android.mk文件是交叉编译c/c++代码时依赖的配置文件,是linux下makefile语法的子集
#获取当前Android.mk文件路径
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
#指定C库文件的名字
LOCAL_MODULE := libHelloWorld
#指定C语言实现的源文件
LOCAL_SRC_FILES := tu_bb_ndk_MainActivity.c \
include $(BUILD_SHARED_LIBRARY)
至于Android.mk要如何编写,大家可以到android-ndk-r7b/docs/ANDROID-MK.html去拷贝
现在我们就可以来实现头文件中的函数了
#include <stdio.h>
#include <jni.h>
#include "tu_bb_ndk_MainActivity.h"
//env代表的是jvm C语言实现的结构体指针,obj代表的是当前调用Java native方法的对象
JNIEXPORT jstring JNICALL Java_tu_bb_ndk_MainActivity_sayHello
(JNIEnv * env, jobject obj)
{
return (*env)->NewStringUTF(env,"Hello World");
}
利用cygwin工具进行交叉编译,生成库文件,位于libs\armeabi目录下,生成libHelloWorld.so库文件
编写Java测试代码,需要注意的是,使用本地方法之前需事先把库文件加载入jvm中,指定要加载的库文件名
package tu.bb.ndk;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends Activity {
private Context mContext;
static{
//事先把库文件加载进jvm,HelloWorld为库文件名字
System.loadLibrary("HelloWorld");
}
//本地方法
public native String sayHello();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
View bt_hw = findViewById(R.id.bt_hw);
bt_hw.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(mContext, sayHello(), Toast.LENGTH_LONG).show();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
好了,HelloWorld就此完成