zoukankan      html  css  js  c++  java
  • android JNI 简单demo(2)它JNI demo 写

    android JNI 简单demo(2)它JNI demo 写

    一、搭建Cygwin 环境:http://blog.csdn.net/androidolblog/article/details/25559013

    二、JNI 基本要素:

    1、编写 含native 方法的java文件。

    2、把该文件用javah 生成 Cygwin 编译库时要用到的头文件,既*.h 文件。

    3、编写*.c 文件。在*.c文件里,实现 *.h 中的方法。

    4、编写mk文件。

    5、配置NDK环境。

    6、用Cygwin 编译库文件。

    7、拷贝库文件到eclipseproject中的JNI demo。

    8、调用 JNI中的native 方法。

    三、JNI demo 编写具体:

    1、编写native 方法的java类

    MyJniMethod .java 
    package com.lin.myjin;

    public class MyJniMethod {
     
      static{
       System.loadLibrary("myJin");
      }
         public native void add(int add);
         public native void print(int i);
         public native int getadd(int add);
    }


    2、把该文件用javah 生成 Cygwin 编译库时要用到的头文件,既*.h 文件:

     生成过程例如以下:下面文字是网上找的。认为写的挺全的。就直接贴了。

     如果你是用Eclipse开发。比如project在 D盘的myjin文件夹中,你有一个类Test.java具有包路径。比如 package cn.edu.xmu.zgy;

    即在D:MyTestsrccneduxmuzgy文件夹下会存放着你的Test.java文件。

    那么要生成.h文件,则在控制台下切换到D:MyTestinclasses文件夹下,然后输入 javah -jni cn.edu.xmu.zgy.Test 之后,就能够在D:MyTestinclasses文件夹下能够找到 cn_edu_xmu_zgy_Test.h头文件。

    原理:eclipse下的androidproject被编译后,会把java生成字节码class文件。所用直接跳转到编译了的project的classes文件夹,然后用java - jni *.class 的文件名称。生成h文件。


    注意

    (1)生成的*.h一定要带包名的h文件。在*.class 文件所在文件夹下, 进行javah -jni * 生成的文件是不带包名的。

    (2)这里的 javah -jni cn.edu.xmu.zgy.Test而不是 javah -jni  cn.edu.xmu.zgy.Test.class


    以下是我生成头文件的截图:project名是 myJin



    生成的com_lin_myjin_MyJniMethod.h 文件例如以下:

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class com_lin_myjin_MyJniMethod */
    #ifndef _Included_com_lin_myjin_MyJniMethod
    #define _Included_com_lin_myjin_MyJniMethod
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class: com_lin_myjin_MyJniMethod
     * Method: add
     * Signature: (I)V
     */
    JNIEXPORT void JNICALL Java_com_lin_myjin_MyJniMethod_add
      (JNIEnv *, jobject, jint);
    /*
     * Class: com_lin_myjin_MyJniMethod
     * Method: print
     * Signature: (I)V
     */
    JNIEXPORT void JNICALL Java_com_lin_myjin_MyJniMethod_print
      (JNIEnv *, jobject, jint);
    /*
     * Class: com_lin_myjin_MyJniMethod
     * Method: getadd
     * Signature: (I)I
     */
    JNIEXPORT jint JNICALL Java_com_lin_myjin_MyJniMethod_getadd
      (JNIEnv *, jobject, jint);
    #ifdef __cplusplus
    }
    #endif
    #endif

    3、编写*.c 文件,在*.c文件里,实现 *.h 中的方法:

    这里以:

    JNIEXPORT jint JNICALL Java_com_lin_myjin_MyJniMethod_getadd
      (JNIEnv * env, jobject obj, jint count)
      {
           return count+8;
     
      }
    为例

    com_lin_myjin_MyJniMethod.c
    文件内容:

    #include "com_lin_myjin_MyJniMethod.h"
    //#define LOG_TAG "Android-T"
    //#undef LOG
    //#include <android/log.h>
    //#define LOGD(a) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,a)
    //#define LOGD2(a,b) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,a,b)
    // #define DBUG
    #include <sys/ioctl.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <termios.h>
    JNIEXPORT void JNICALL Java_com_lin_myjin_MyJniMethod_add
      (JNIEnv * env, jobject obj, jint count)
      {
     
      }
    /*
     * Class: com_lin_myjin_MyJniMethod
     * Method: print
     * Signature: (I)V
     */
    JNIEXPORT void JNICALL Java_com_lin_myjin_MyJniMethod_print
      (JNIEnv * env, jobject obj, jint count)
      {
     
      }
    /*
     * Class: com_lin_myjin_MyJniMethod
     * Method: getadd
     * Signature: (I)I
     */
    JNIEXPORT jint JNICALL Java_com_lin_myjin_MyJniMethod_getadd
      (JNIEnv * env, jobject obj, jint count)
      {
           return count+8;
     
      }

    4、编写mk文件:
    关于MK文件。可自行了解。

    在此不赘述。


    Android.mk文件:
    内容:
    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_MODULE := myJin
    LOCAL_SRC_FILES := com_lin_myjin_MyJniMethod.c
    include $(BUILD_SHARED_LIBRARY)

    5、配置NDK环境:
    在这里。NDK不用配置环境变量。原理是用绝对路径操作命令。

    在Cygwin下,跳转到你 C文件 h文件 mk 文件的文件夹。或者把这三个文件复制到一个叫jni的文件夹以下。文件夹名字能够随便取。
    然后跳转到含有这三个文件的文件夹,输入:/cygdrive/d/android-ndk-r5b/ndk-build  回车。

    /cygdrive/d/这个部分依据你 存放android-ndk-r5b/ndk-build的文件夹变化而变化。仅仅要能直接精确到android-ndk-r5b/ndk-build 即可。

    原理:$符号取加入在环境变量中的 命令或者文件夹。


    举例:自己定义一个myCommand 命令,实现命令是 cd .  .   即跳转到上层文件夹。
    加入myCommand 成功后。能够直接用 $myCommand 来实现 cd  .. 
    所以:网上的NDK-Build 命令 事实上是/cygdrive/d/android-ndk-r5b/ndk-build  的方便操作模式。前提是你加入了NDK-Build环境变量。
    myCommand 命令截图:

    6、用Cygwin 编译库文件步骤:

    (1)新建一个jni文件夹:


    (2)文件夹以下放三个文件: 跳转到对应文件夹 输入:/cygdrive/d/android-ndk-r5b/ndk-build  回车

     


    生成的库文件:



    6、拷贝库文件到eclipseproject中的project,这里是myJin:这个名字本来是打算打myJni的。大家当做project名就好。


    注意:

      (1)库文件名称通常是lib**.so  载入时名字是 **.so 比方上面的 库文件是libmyJin.so 而载入处是 myJin

      (2)载入库时。文件名称不带库文件后缀 .so

    (3)载入库代码块 要静态载入。

     


    7、调用 JNI中的native 方法:


    执行结果是:


    可见 加过是12  也就是4+8的结果。说明代码已经正常调用。

    projectdemo源代码链接:http://download.csdn.net/detail/linhuorongandroid/7332143

    结语:该代码demo上十分简单。目的仅仅是跑个JNI流程。有所不足。多多不吝赐教。



    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    第一次博客作业
    编辑器、编译器、文件、IDE等常见概念辨析
    树、二叉树、查找知识点总结
    二叉排序树
    线性表知识点总结
    c语言文件
    第二次博客作业: 函数+进制转换器v1.0beta
    python作业1
    c语言知识
    第一次博客作业
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4684070.html
Copyright © 2011-2022 走看看