Android NDK开发篇(三):NDK开发步骤

  开始学习NDK开发,首先以输出Hello World实例开始讲解。

  NDK的开发步骤:

  1、在Java文件中声明native方法

public class TestActivity extends Activity {

	static {
		System.loadLibrary("my-ndk");
	}
	
	// 声明JNI层的原生方法,使用native关键字
	public native String stringFromJNI();
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		TextView tvText = new TextView(this);
		tvText.setText(stringFromJNI());
		setContentView(tvText);
	}

}


  2、编译Java文件

  直接用javac命令编译声明native方法的Java文件

  shamoo的工程目录在E:\project\test

  在cmd中,输入cd E:\project\test

  javac src\com\shamoo\jni\HelloJni.java -d bin\classes

  -d指定.class文件的输出目录

  也可以使用eclipse直接生成,生成的目录在工程目录的bin\classes


  3、使用javah命令生成头文件

  关于javah命令,Shamoo也折腾了一段时间,一直使用命令失败,总是提示不能访问Android sdk的类,后来用-classpath指定src的位置就可以了,具体原因不明...

  javah -classpath src -d jni -jni com.shamoo.activity.TestActivity

  如果声明native方法的类中没有使用Android sdk的类就可以使用以下命令,例如HelloJni声明了navtive方法

  javah -classpath bin/classes -d jni -jni com.shamoo.jni.HelloJni

  -classpath指定.class文件的根目录 -d指定输出目录 -jni指定声明了native方法的类。javah是根据.class文件反编译生成头文件的

  生成的头文件如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_shamoo_activity_TestActivity */

#ifndef _Included_com_shamoo_activity_TestActivity
#define _Included_com_shamoo_activity_TestActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_shamoo_activity_TestActivity
 * Method:    stringFromJNI
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_shamoo_activity_TestActivity_stringFromJNI
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif


  从头文件可以看出,原生方法必须指定Java + 原生方法的包名(点用下划线代替) + 方法名

  4、编写头文件对应的源文件 com_shamoo_activty_TestActivity.cpp

#include <jni.h>
#include <stdio.h>
#include <com_shamoo_activity_TestActivity.h>

JNIEXPORT jstring JNICALL Java_com_shamoo_activity_TestActivity_stringFromJNI
  (JNIEnv *env, jobject) {
	printf("Hello World");

	return env->NewStringUTF("Hello World");
}
  是不是很熟悉,printf("Hello World");不过printf默认不会输出到Log里面,需要设置一下才可以。这次编写源文件就不需要再写extern "C"标志,因为自动生成的头文件已经帮我们完成啦!


  5、修改Android.mk文件

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := my-ndk
LOCAL_SRC_FILES := my-ndk.cpp com_shamoo_activity_TestActivity.cpp
LOCAL_LALIBS += -llog

include $(BUILD_SHARED_LIBRARY)

  Android.mk其实就是Makefile,分析一下上面的几个环境变量

  LOCAL_PATH指定源码的目录,$(call my-dir),学过Linux Shell再熟悉不过了

  LOCAL_MODULE编译生成的.so库

  LOCAL_SRC_FILES指定加入编译的源文件

  LOCAL_LALIBS指定其他库,-l + 库名,例如上述要使用到NDK的LOG就要使用log库

  include导入一些Makefile的片段,比如导入CLEAR_VARS会在配置之前清除以前的环境变量,以免编译的时候受到其他环境变量的影响,BUILD_SHARED_LIBRARY是导入其他的共享库


  好的直接编译,执行,没问题就会看到一个Activity显示Hello World的文本啦!

你可能感兴趣的:(android,jni,NDK,native)