make APP=test-jni -B命令去编译jni,功能同$NDK/ndk-build。但是前提条件是要写好application.mk和android.mk
Android.mk是一个makefile,用来告诉NDK需要编译哪些文件,生成哪些模块。
Application.mk的作用是告诉Android SDK需要哪些库文件。如:
--------------------------------------------------
APP_PROJECT_PATH := $(call my-dir)
APP_MODULES := mylib
-----------------------------------
APP_PROJECT_PATH代表android工程所在目录,在本例中它被放在<project>中; APP_MODULES表示工程需要的库,如果有多个以空格分开。
--- NDK开发捷径 ---
这里先扯一句题外话 -- 如果你不需要使用NDK开发,只是需要使用第三方用NDK开发的库,那么你只需要这样做:
把第三方提供的libxxx.so放到你的<project>/libs/armeabi/下, 然后在程序随便什么地方中加入
static {
System.loadLibray("xxx");
}
就可以使用该库了。
/* Irrlicht中android.mk的写法 */
LOCAL_LDLIBS := -lGLESv1_CM -ldl -llog 其中GLESv1_CM指的是opengl ES的lib库,libdl.so;liblog.so
libGLESv1_CM.so是OpenGL ES 1.x的库,libGLESv2.so是OpenGL ES 2.x的库
LOCAL_LDLIBS 和LOCAL_SHARED_LIBRARIES的区别:
in your case, in your “mydrdoid”, if you use:LOCAL_LDLIBS := -lskia” …then, libskia.so *need not* be rebuilt.
whereas, if you use:LOCAL_SHARED_LIBRARIES := libskia … then libskia.so *will* be rebuilt if there are any changes in it’s dependencies.
NDK编程详解【转】
http://hi.baidu.com/%B0%A2%D2%E4%CD%F9/blog/item/eeca3319d07bf8e1af5133d4.html
其中有各个部分的写法,包括application.mk和android.mk的写法,内容很全面。
首先我们来看一下整体的工程的目录结构:
好了,底下我们就开始做我们的ndk程序了,第一步:创建一个Jni类,这个类用于编写一些我们待会儿要在c文件中实现的方法:
具体代码如下:
package com.zhangfu.ndk;
public class Jni {
public native int getSum(int x,int y);
}
第二步我们就开始利用我们的javac命令来编译我们的jni.java文件
我们把src目录底下的Jni.java文件复制到该工程的bin目录底下,然后再再cmd下定位目录到该工程的bin下,然后执行:
javac Jni.java
执行完后,在bin目录下会
出现一个Jni.class文件,然后我们在用javah -jni com.zhangfu.ndk.Jni命令就可以在bin目录下出现com_zhangfu_ndk_Jni.h文件,然后我们要做两个动作:第一个是将我们刚刚生成的Jni.class文件复制到bin目录底下的包结构底下覆盖原来的Jni.class文件,第二个动作是我们要在工程的根目录底下创建一个jni文件夹把我们生成的com_zhangfu_ndk_Jni.h文件拷贝到该文件夹下。
注释:.clsaa和.h文件可以一起生成
javac JNITest.java && javah JNITest
com_zhangfu_ndk_Jni.h文件如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_zhangfu_ndk_Jni */
#ifndef _Included_com_zhangfu_ndk_Jni
#define _Included_com_zhangfu_ndk_Jni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_zhangfu_ndk_Jni
* Method: getSum
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_com_zhangfu_ndk_Jni_getSum
(JNIEnv *, jobject, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
这个文件是自动生成的,我们不需要去手工编写,然后我们需要编写一个c文件来实现我们的两个数相加的功能,
c语言文件com_zhangfu_ndk_Jni.c如下(具体的编写方法是:我们将com_zhangfu_ndk_Jni.h文件中的函数复制过来,然后改写一下方法体就可以了,这一步不怎么难的,相信大家都可以做到的。):
#include<jni.h>
#include<stdio.h>
jint JNICALL Java_com_zhangfu_ndk_Jni_getSum
(JNIEnv* env, jobject thiz, jint x, jint y)
{
return x+y;
}
我们的c文件写好后,我们就要把这个文件放置到我们前面创建的jni文件夹下了。底下一步我们就要为我们生成so文件做准备了(创建我们的Android.mk和Application.mk文件),
Android.mk文件:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := GetSum
LOCAL_SRC_FILES := com_zhangfu_ndk_Jni.c
include $(BUILD_SHARED_LIBRARY)
Android.mk文件存放目录:
Application.mk文件:
APP_PROJECT_PATH := $(call my-dir)/project
APP_MODULES := GetSum
Application.mk文件存放目录:
然后我们就得拿出我们的工具Cygwin来使用了
这个工具的使用和下载我就不讲了,这个网上有很多的资料,大家可以到网上去搜索一下,如果实在找不到的可以留下邮箱,呵呵,你懂的。然后我们使用的命令式:
先定位到我们的ndk根目录下,然后执行底下的命令:
$ make APP=GetMax
Android NDK: Building for application 'GetMax'
Compile thumb : GetMax <= com_zhangfu_ndk_Jni.c
SharedLibrary : libGetMax.so
Install : libGetMax.so => apps/GetMax/project/libs/armeabi/libGetMax.so
然后我们的工程中就会自动创建一个libs目录,这个目录底下是我们成功运行上面的命令后生成的so文件存放目录。
然后我们就可以在Activity类中调用我们手工生成的动态链接文件了。
具体的GetSum.java文件如下:
package com.zhangfu.ndk;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
public class GetSum extends Activity {
static
{
//加载动态链接文件
System.loadLibrary("GetSum");
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//用手动创建布局文件
LinearLayout layout=new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
final EditText oper1=new EditText(this);
final EditText oper2=new EditText(this);
final TextView tv=new TextView(this);
Button btn=new Button(this);
btn.setText("计算");
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(!oper1.getText().toString().trim().equals("")&&!oper2.getText().toString().trim().equals(""))
{
int op1=Integer.parseInt(oper1.getText().toString());
int op2=Integer.parseInt(oper2.getText().toString());
//生成jni对象一边调用用c编写的动态链接文件
Jni jni=new Jni();
tv.setText(jni.getSum(op1, op2)+"");
}
}
});
layout.addView(oper1);
layout.addView(oper2);
layout.addView(tv);
layout.addView(btn);
setContentView(layout);
}
}
就这样我们的这个工程就这么的实现了,底下是效果图: