当前位置: 代码迷 >> Android >> Android-JNI筹建以及调用
  详细解决方案

Android-JNI筹建以及调用

热度:36   发布时间:2016-04-28 02:22:15.0
Android-JNI搭建以及调用

转载请注明出处,谢谢~

首先要新建一个工程,起名HelloJni。然后在工程目录下新建文件夹jni。如图:

我用的是eclipse


然后我们用快捷键Alt+Enter进入工程属性选项,选择左边栏的builder,然后点击new:


之后我们选择program,然后会有一个弹出窗口:


在main选项中设置好两个路径,第一个是ndk里ndk-build.cmd的路径,我这里用的是ndk-r9,第二个是工程路径,就是我们的HelloJni工程,然后再看refresh选项:


把如图所示的勾选上,然后看options选项:


把如图所示勾选上之后会报个错,此时ok不能点,然后我们点Specify Resources...选项,进入另一个界面:


在这里我们选择HelloJni项目的jni目录,点击finish完成。然后点击ok设置完成。

之后我们写我们的jni的头文件:

我们要在src中新建一个类,类里写上我们要用到的native方法:

package com.ocean.hellojni.jni;public class JniClient {		public static native String getString(String a,String b);	public static native int getInt(int a,int b);}

然后如果是用eclipse,会自动生成classes文件,其他的可能需要手动生成一下,然后我们用cmd命令行生成头文件:


方法是首先进入到HelloJni工程的目录下,然后进入bin的classes目录,之后执行语句javah path。path是你写的native本地方法那个类的全路径,就是包名,路径加上方法名,不需要后缀名,之后就生成好了.h的头文件,然后将它拷贝到jni目录,打开:

/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class com_ocean_hellojni_jni_JniClient */#ifndef _Included_com_ocean_hellojni_jni_JniClient#define _Included_com_ocean_hellojni_jni_JniClient#ifdef __cplusplusextern "C" {#endif/* * Class:     com_ocean_hellojni_jni_JniClient * Method:    getString * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_ocean_hellojni_jni_JniClient_getString  (JNIEnv *, jclass, jstring, jstring);/* * Class:     com_ocean_hellojni_jni_JniClient * Method:    getInt * Signature: (II)I */JNIEXPORT jint JNICALL Java_com_ocean_hellojni_jni_JniClient_getInt  (JNIEnv *, jclass, jint, jint);#ifdef __cplusplus}#endif#endif
根据它写我们的C/C++文件:

#include "com_ocean_hellojni_jni_JniClient.h"#include <stdio.h>#include <stdlib.h>#ifdef __cplusplusextern "C" {#endif/* * Class:     com_ocean_hellojni_jni_JniClient * Method:    getString * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_ocean_hellojni_jni_JniClient_getString  (JNIEnv *env, jclass arg, jstring strA , jstring strB) {	jstring str = (*env)->NewStringUTF(env,"Hello Jni!");	return str;}/* * Class:     com_ocean_hellojni_jni_JniClient * Method:    getInt * Signature: (II)I */JNIEXPORT jint JNICALL Java_com_ocean_hellojni_jni_JniClient_getInt  (JNIEnv *env, jclass arg, jint a , jint b){	return a+b;}#ifdef __cplusplus}#endif

此处应注意方法名要和头文件的一致。

然后我们写.mk文件:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := HelloJniLOCAL_SRC_FILES := com_ocean_hellojni_jni_JniClient.cinclude $(BUILD_SHARED_LIBRARY)
C和C++的.mk文件可能略有不同,但大致都是这样,详情以后的博文里也许会提到。

然后再java类中调用我们写的本地方法:

package com.ocean.hellojni;import android.app.Activity;import android.os.Bundle;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.EditText;import android.widget.TextView;import com.ocean.hellojni.jni.JniClient;public class MainActivity extends Activity {	private TextView show;	private TextView answer;	private EditText one;	private EditText two;		static{		System.loadLibrary("HelloJni");	}		@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.activity_main);		show = (TextView) findViewById(R.id.show);		answer = (TextView) findViewById(R.id.answer);		one = (EditText) findViewById(R.id.et_one);		two = (EditText) findViewById(R.id.et_two);		String string = JniClient.getString("1","2");		show.setText(string);				answer.setOnClickListener(new OnClickListener() {			@Override			public void onClick(View arg0) {				if (one.getText().toString() != null && two.getText().toString() != null						&& !one.getText().toString().equals("") && !two.getText().toString().equals("")) {					int i = JniClient.getInt(Integer.valueOf(one.getText().toString()),							Integer.valueOf(two.getText().toString()));					answer.setText("result : "+i);				}			}		});	}	@Override	public boolean onCreateOptionsMenu(Menu menu) {		getMenuInflater().inflate(R.menu.main, menu);		return true;	}}
执行看结果:




OK!此处应该有掌声~~


1楼cheyiliu昨天 17:38
  相关解决方案