当前位置: 代码迷 >> Android >> Android NDK开发篇(3):NDK开发步骤
  详细解决方案

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

热度:8   发布时间:2016-04-28 06:08:16.0
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 __cplusplusextern "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-ndkLOCAL_SRC_FILES := my-ndk.cpp com_shamoo_activity_TestActivity.cppLOCAL_LALIBS += -lloginclude $(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的文本啦!

  相关解决方案