一个完整的NDK编译过程

1、创建android工程

2、编写JAVA类,其中包含nativie方法

        例如:

public class JNI {
 public native void write();
 public native void myOpen(String pathname);
}

3、生成JNI头文件

使用javah命令

使用cmd进入android项目的bin目录中,然后执行 javah -classpath . -jni com.android.myjni.JNI这个命令

 

用法:javah [选项] <类>

其中 [选项] 包括:

-help                 输出此帮助消息并退出

-classpath <路径>     用于装入类的路径

-bootclasspath <路径> 用于装入引导类的路径

-d <目录>             输出目录

-o <文件>             输出文件(只能使用 -d 或 -o 中的一个)

-jni                  生成 JNI样式的头文件(默认)

-version              输出版本信息

-verbose              启用详细输出

-force      始终写入输出文件

 

com.android.myjni.JNI指包com.android.myjni下的JNI类,是要生成该类的JNI头文件

 

例如:com_android_myjni_JNI.h

-* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
-* Header for class com_android_myjni_JNI */
#ifndef _Included_com_android_myjni_JNI
#define _Included_com_android_myjni_JNI
#ifdef __cplusplus
extern "C" {
#endif
-*
 * Class:     com_android_myjni_JNI
 * Method:    write
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_android_myjni_JNI_write
  (JNIEnv *, jobject);
-*
 * Class:     com_android_myjni_JNI
 * Method:    myOpen
 * Signature: (Ljava/lang/String;)I
 */
JNIEXPORT void JNICALL Java_com_android_myjni_JNI_myOpen
  (JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif

 

4、编写c代码

例如:com_android_myjni_JNI.c 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include "com_android_myjni_JNI.h"
JNIEXPORT void JNICALL Java_com_android_myjni_JNI_write
  (JNIEnv *e, jobject j)
{
 FILE* f = fopen("/sdcard/11.txt","w+");
 fprintf(f, "aaaaaaaaaaaaa");
 fclose(f);
}
JNIEXPORT void JNICALL Java_com_android_myjni_JNI_myOpen
  (JNIEnv *e, jobject j, jstring pathname)
{
 //从jstring类型取得c语言环境下的char*类型 
    const char* name = (*e)->GetStringUTFChars(e, pathname, 0);
 int fd;
 ssize_t size;
 char s[] = "Linux open!/n";
 char buffer[80];
 fd = open(name, O_RDWR|O_CREAT|O_APPEND);
 if(-1 == fd)
 {
  printf("open %s error!/n", name);
 }
 else
 {
  printf("open %s success!/n", name);
  size = write(fd, s, sizeof(s));
  printf("wirte %d bytes!/n", size);
  memset(buffer, '/0', sizeof(buffer));
  size = read(fd, buffer, sizeof(buffer));
  printf("read %d bytes!/n", size);
  close(fd);
  printf("%s/n", buffer);
 }
 //释放jni分配的内存 
    (*e)->ReleaseStringUTFChars(e, pathname, name);
}
 
5、编写Android.mk
  例如:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := myjni
LOCAL_SRC_FILES := com_android_myjni_JNI.c
include $(BUILD_SHARED_LIBRARY)
6、编译so文件
进行编译so文件:
进入工程目录,执行 ndk-build,例如:~/workspace/MYJni$ ndk-build

则会在libs/armeabi/生成相应的so文件,例如:libmyjni.so

 

工程目录结构:

src下包含java文件

自己新建一个jni文件,包含com_android_myjni_JNI.h、com_android_myjni_JNI.c、Android.mk文件

so文件会自动在libs/armeabi/下生成

 

测试代码:

package com.android.myjni; 
import android.app.Activity; 
import android.os.Bundle; 
public class JniTest extends Activity { 
    static { 
        System.loadLibrary("myjni"); 
    
  
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
         
        JNI j = new JNI(); 
        j.write(); 
        j.myOpen("/sdcard/12.txt"); 
   

from:http://blog.csdn.net/student_cui/article/details/6249129

posted @ 2015-07-03 06:28  Anzhongliu  阅读(443)  评论(0编辑  收藏  举报