现在的位置: 首页 > 综合 > 正文

JNI入门

2013年08月17日 ⁄ 综合 ⁄ 共 2307字 ⁄ 字号 评论关闭
编写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就此完成

抱歉!评论已关闭.