android ndk jni 编程入门例子

本文详细介绍如何在Windows环境下配置Android NDK开发环境,并通过实例演示如何利用JNI编写C/C++代码实现一个简单的数组创建功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

网上这方面的文章其实也很多.但多数知识点比较零散. 正好最近学着了一下这方面的知识. 因此有个写这篇分享的冲动. 废话就少说了,直接开始.

 

必备条件:

1. 操作系统windows(linux和windows其实都基本一样,下载对应版本的android sdk,nkd,eclipse就ok了)

2. 安装android sdk <http://developer.android.com/sdk/index.html>

3. 安装android ndk <http://developer.android.com/sdk/ndk/index.html>

4. IDE Eclipse           <http://www.eclipse.org/downloads/>

5. 安装 Eclipse android 开发插件

 

设置环境变量:

(假定sdk和ndk都保存在D盘)

1. D:\android-ndk-r7;

2. D:\android-sdk-windows\tools

 

新建一个android app project:

1. 启动eclipse 

2. 新建一个 Android Project

3. 在JnitestActivity的class 里面添加一个native 的函数,如下图. 

    native static int[] createArray(int size);  这是一个根据size创建一个int 数组,大小为size的值.

package com.jnitest;

import android.app.Activity;
import android.os.Bundle;

public class JnitestActivity extends Activity {
    /** Called when the activity is first created. */
    
    native static int[] createArray(int size);
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

4. 生成头文件(.h文件):

   1) 打开cmd:开始->运行->输入"cmd"->确定.

   2) 去到Android Project工程的目录.

   3) 输入命令"javah -classpath bin/classes -d jni com.jnitest.JnitestActivity"生成头文件.

       这里解释一下这条命令.这是一条javah的命令.

       -classpath bin/classes 这个参数指定的是保存.class文件的根目录.注意,这里有可能是, -classpath bin. 反正都尝试一下.

       -d jni 这里指定最后输出的.h文件保存的位置, 一般的android工程都是使用一个jni的目录保存所有的C/C++代码文件.建议不要其他名字的目录了.

       com.jnitest.JnitestActivity 这个参数指定的是,从android工程source file为根目录,指定到有native 函数的class. 举例,从上面的代码中,可以看到package 是   com.jnitest,然后类的名字是JnitestActivity.把他们拼起来,就是com.jnitest.JnitestActivity了.

   4) 命令执行完后,会看到工程目录下多了一个jni文件夹,里面有一个.h文件.如下图所示.

 

5. 写C/C++实现这个函数.

    1) 打开.h文件,就能看到java那个native函数对应的C/C++函数的样子,即下面的

JNIEXPORT jintArray JNICALL Java_com_jnitest_JnitestActivity_createArray(JNIEnv *, jclass, jint);
#ifndef _Included_com_jnitest_JnitestActivity
#define _Included_com_jnitest_JnitestActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_jnitest_JnitestActivity
 * Method:    createArray
 * Signature: (I)[I
 */
JNIEXPORT jintArray JNICALL Java_com_jnitest_JnitestActivity_createArray
  (JNIEnv *, jclass, jint);

#ifdef __cplusplus
}
#endif
#endif


  2) 新建一个cpp文件放在jni目录下,代码内容如下.

      具体每行什么意思,这里就不不讲解了.

      <http://java.sun.com/docs/books/jni/download/jni.pdf>这个官方文档有非常详细的解说.

#include "com_jnitest_JnitestActivity.h"

JNIEXPORT jintArray JNICALL Java_com_jnitest_JnitestActivity_createArray
  (JNIEnv *jenv, jclass jcls, jint jsize)
{
    int size = (jint) jsize;
    jint arr[256];
    jintArray jarr = jenv->NewIntArray(size);
    jenv->SetIntArrayRegion(jarr, 0, size, (jint *) &arr[0]);
    return jarr;
}

 

6. 编写一个android.mk文件,放在jni目录下.

    其中 LOCAL_MODULE := test-jni ,表示编译出来的动态链接库的名字.编译出来的文件名字是"libtest-jni.so",其中"lib"和".so"是自动添加的前缀和后缀.

    LOCAL_SRC_FILES := com_jnitest.JnitestActivity.cpp 指明需要编译的.cpp文件.

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := test-jni
LOCAL_SRC_FILES := com_jnitest_JnitestActivity.cpp
                    
LOCAL_LDLIBS    := -llog
  
LOCAL_PRELINK_MODULE := false

include $(BUILD_SHARED_LIBRARY)

 

7. 编译动态链接库文件.

  1) 启动cmd

  2) 跳转到该 android 工程的目录

  3) 生成build.xml文件,使用命令: "android update project -p . -s"

  4) 输入"ndk-build", 编译完成.生成动态链接库文件(.so文件)保存在工程目录的libs/armeabi/目录下.


8. 修改JnitestActivity.java的代码,调用动态链接库中的函数.

package com.jnitest;

import android.app.Activity;
import android.os.Bundle;

public class JnitestActivity extends Activity {
    /** Called when the activity is first created. */
    
    static
    {
        System.loadLibrary("test-jni");
    }
    
    native static int[] createArray(int size);
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        int[] arr = createArray(20);
        System.out.println(arr.length);
    }
}

上面的程序调用了createArray这个函数,返回一个int[].

这里我把数组的长度打印出来了.从LogCat中可以看到如下.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值