zoukankan      html  css  js  c++  java
  • NDK Demo 程序

    简单的 NDK Demo 程序

           好了,环境已搭建好, 现在我们开始建立一个简单的 ndk 程序来体验下整个 ndk 开发流程 :

    第一步:首先我们在eclipse 中新建一个工程,工程名这里是NdkPassNormalData 。   在工程   中新建一个java 类:CallNativeDemo.java

    内容如下:

    package com.jiubang.Demo.Ndk.PassNormalData;

    public class CallNativeDemo {

     static {

           System.loadLibrary ( "NdkPassDataDemo" );

    // 注意库文件名,对于 NdkPassDataDemo 系统会在该类初始化时加载 //libNdkPassDataDemo.so 库 , 切记勿画蛇添足加上前面的 lib 与 .so 扩展名

        }

        public native int Sum( int a , int b); // 加上 native 表示该方法由 .so 实现

        public native String StrCat(String str1 , String str2);

    }

    编写好该 java 文件后,先编译,然后用 javah 生成 ndk 中我们需要的 c 头文件 :

    进入到工程的 bin 目录下输入:

    javah  -jni com.jiubang.Demo.Ndk.PassNormalData.CallNativeDemo

    然后会在当前目录下生成com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo.h 文件

    内容大概如下:

    /* DO NOT EDIT THIS FILE - it is machine generated */

    #include <jni.h>

    /* Header for class com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo */

    #ifndef _Included_com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo

    #define _Included_com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo

    #ifdef __cplusplus

    extern "C" {

    #endif

    /*

      * Class:     com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo

      * Method:    Sum

      * Signature: (II)I

      */

    JNIEXPORT jint JNICALL Java_com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo_Sum

      (JNIEnv *, jobject, jint, jint);

    /*

      * Class:     com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo

      * Method:    StrCat

      * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;

      */

    JNIEXPORT jstring JNICALL Java_com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo_StrCat

      (JNIEnv *, jobject, jstring, jstring);

    #ifdef __cplusplus

    }

    #endif

    #endif

    第二步:在我们新的工程中加一个名为:jni 的文件夹。这个文件夹就是放原生态c/c++ 的源码的地方,我们make 的时候cygwin 就是编译这个文件夹的。

    第三步:在jni 文件夹里新建一个Android.mk 文件。注意,后缀为.mk , 且文件夹一定要小写

    Android.mk 的内容为: 

    LOCAL_PATH := $(call my-dir) <--------- 返回当前路径,默认的,不需要更改

    include $(CLEAR_VARS)      <-------- 清除先前定义的环境变量,默认的,不需要更改

    LOCAL_MODULE := NdkPassDataDemo <-------- 在 java 类引用时的名称

    LOCAL_CPP_EXTENSION := cpp

    LOCAL_SRC_FILES := Fun.cpp <------ 需要编译的源文件

    LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib –llog <-- 打 log 要用到的库,这里暂时不大明白为什么库名是这样 …

    include $(BUILD_SHARED_LIBRARY) <-- 这里指的是动态库,默认的,不需要更改

    第四步:在jni 文件夹里新建一个 Fun.cpp 的文件。这个文件就是c/c++ 文件。

                 Fun.cpp 的内容为:

    #include <stdio.h>

    #include <stdlib.h>

    #include <string.h>

    #include <android/log.h>

    #include "com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo.h"

    // 对应 public native int Sum( int a , int b) 的实现

    jint JNICALL Java_com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo_Sum(JNIEnv* aEnv, jobject aThis, jint aParamA, jint aParamB)

    {

        int sum = 0;

        __android_log_print(ANDROID_LOG_INFO , "Ndk_PassNormalData" , "CallNativeDemo_Sum Coming");

        sum = aParamA + aParamB;

        FILE* file = fopen("/sdcard/hello.txt","w+");

        if (file != NULL)

        {

           fputs("HELLO WORLD!/n", file);

           fflush(file);

           fclose(file);

        }

        __android_log_print(ANDROID_LOG_INFO , "Ndk_PassNormalData" , "CallNativeDemo_Sum Leaving");

        return sum;

    }

    // 对应 public native String StrCat(String str1 , String str2) 实现

    jstring JNICALL Java_com_jiubang_Demo_Ndk_PassNormalData_CallNativeDemo_StrCat(JNIEnv *aEnv, jobject aThis, jstring aStr1, jstring aStr2)

    {

        __android_log_print(ANDROID_LOG_INFO , "Ndk_PassNormalData" , "CallNativeDemo_StrCat Coming");

        const char* str1 = aEnv->GetStringUTFChars(aStr1 , 0);

        const char* str2 = aEnv->GetStringUTFChars(aStr2 , 0);

        //char* str1 = (char*)(*aEnv)->GetStringUTFChars(aEnv ,aStr1 , 0);

        //char* str2 = (char*)(*aEnv)->GetStringUTFChars(aEnv ,aStr2 , 0);

        int str1_len = strlen(str1);

        int str2_len = strlen(str2);

        // char* pszRet = malloc(str1_len + str2_len + 1);

        char* pszRet = new char[str1_len + str2_len + 1];

        strcpy(pszRet, str1);

        strcat(pszRet, str2);

        //jstring jstrRet = (*aEnv)->NewStringUTF(aEnv, pszRet);

        jstring jstrRet = aEnv->NewStringUTF(pszRet);

        // free(pszRet);

        delete pszRet;

        __android_log_print(ANDROID_LOG_INFO , "Ndk_PassNormalData" , "CallNativeDemo_StrCat Leaving");

        return jstrRet;

    }

    然后就可以开始编译了 :

    打开 cygwin, 进入到工程的 jni 目录,然后执行 ndk-build

    有看到 Install 就 OK 了

    然后会发现工程目录下会多了一个 lib 与 obj 的目录

    最后在 android 工程里加上调用这些 ndk 本地方法的代码:

    CallNativeDemo nativeDemo = new CallNativeDemo();  

    int value = nativeDemo.Sum(10, 20);  

    String str = nativeDemo.StrCat("who", "are you");  

    TextView v = (TextView)findViewById(R.id.textview1);  

    v.setText(str);   

  • 相关阅读:
    安装IDEA
    缓存工具CacheUtil
    使用Eclipse上传/下载Git项目
    Sublime文本排序&查找重复行&删除重复行
    Sublime Text 3 配置Java开发
    安装XMind
    安装Maven
    安装MySQL
    安装Eclipse及相关Plugin
    Android Xposed框架中创建模块的指导手册
  • 原文地址:https://www.cnblogs.com/hummersofdie/p/2407720.html
Copyright © 2011-2022 走看看