zoukankan      html  css  js  c++  java
  • Android JNI和NDK学习(02)静态方式实现JNI

    Android JNI和NDK学习(02)--静态方式实现JNI

    JNI包括两种实现方法:静态和动态。两种方法的区别如下:

    静态:先由Java得到本地方法的声明,然后再通过JNI实现该声明方法。

    动态:先通过JNI重载JNI_OnLoad()实现本地方法,然后直接在Java中调用本地方法。

    本文介绍静态实现方式,下一篇会介绍动态实现方式。

    1 首先,在Eclipse下新建一个工程myndk

    Myndk.java的代码如下:

     1 package com.skywang.ndk;
     2  
     3  import android.app.Activity;
     4  import android.os.Bundle;
     5  import android.widget.TextView;
     6  
     7  public class Myndk extends Activity {
     8      
     9      @Override
    10      public void onCreate(Bundle savedInstanceState)
    11      {
    12          super.onCreate(savedInstanceState);
    13  
    14          TextView  myTextView = new TextView(this);
    15          myTextView.setText( HelloNdk() );
    16          setContentView(myTextView);
    17      }
    18  
    19      public native String  HelloNdk();
    20  
    21      static {
    22          System.loadLibrary("hello_jni");
    23      }
    24 }
    View Code

      

    2 运行工程,生成.class文件

    检查bin目录,若有生成Myndk.class;则继续下一步。生成.class文件的目的,是为下一步生成.h头文件做准备。

    3 编译生成.h文件

    打开终端,切换到工程所在目录。假设工程目录为“/hom/skywang/workspace/ndk/myndk”,则通过以下命令切换目录:

    $ cd /home/skywang/workspace/ndk/myndk/

    查看文件列表

    $ ls
    $ AndroidManifest.xml  assets  bin  gen  proguard-project.txt  project.properties  res  src

    新建jni目录,并查看文件列表

    $ mkdir jni; ls
    $ AndroidManifest.xml  assets  bin  gen  jni  proguard-project.txt  project.properties  res  src

    生成javah文件

    $ javah -classpath bin/classes -d jni com.skywang.ndk.Myndk

    -classpath:后面接“类的路径”。
    -d : 后面接“生成的头文件存放的目录”,d表示destination。
    com.example.hellojni.HelloJni:是完整类名。

    上诉命令生成的的.h文件路径:jni/com_skywang_ndk_Myndk.h 

    生成文件内容:

     1 /* DO NOT EDIT THIS FILE - it is machine generated */
     2  #include <jni.h>
     3  /* Header for class com_skywang_ndk_Myndk */
     4  
     5  #ifndef _Included_com_skywang_ndk_Myndk
     6  #define _Included_com_skywang_ndk_Myndk
     7  #ifdef __cplusplus
     8  extern "C" {
     9  #endif
    10  /*
    11   * Class:     com_skywang_ndk_Myndk
    12   * Method:    HelloNdk
    13   * Signature: ()Ljava/lang/String;
    14   */
    15  JNIEXPORT jstring JNICALL Java_com_skywang_ndk_Myndk_HelloNdk
    16    (JNIEnv *, jobject);
    17  
    18  #ifdef __cplusplus
    19  }
    20  #endif
    21  #endif
    View Code

      

    补充:若执行javah命令时,遇到如下错误。是因为-classpath后面所接的路径不对!

    error: cannot access com.skywang.ndk.Myndk
    class file for com.skywang.ndk.Myndk not found
    javadoc: error - Class com.skywang.ndk.Myndk not found.
    Error: No classes were specified on the command line. Try -help.

    有了com_skywang_ndk_Myndk.h头文件之后,我们就可以实现该头文件中声明的函数。

    4 实现头文件中声明的函数

    新建文件jni/hello_jni.c。hello_jni.c的代码如下:

    #include <string.h>
    #include <jni.h>
     
    JNIEXPORT jstring JNICALL Java_com_skywang_ndk_Myndk_HelloNdk
      (JNIEnv* env, jobject obj)
    {
        return (*env)->NewStringUTF(env, "Hello JNI!");
    }

     hello_jni.c的作用就是实现com_skywang_ndk_Myndk.h中声明的函数。

    5 编写实现函数对应的Android.mk

    添加文件jni/Android.mk,内容如下:

    LOCAL_PATH := $(call my-dir)
     
    include $(CLEAR_VARS)
    
    LOCAL_MODULE    := hello_jni
    LOCAL_SRC_FILES := hello_jni.c
         
    include $(BUILD_SHARED_LIBRARY)

      

    6 编译生成库文件

    进入到工程所在目录,执行ndk-build,编译生成.so库文件。

    $ cd /home/skywang/workspace/ndk/myndk/
    $ ndk-build

     生成库文件所在目录:libs/armeabi/libhello_jni.so

    7 重新运行工程

    重新运行eclipse下的myndk工程。输出如下:

  • 相关阅读:
    Python File readline() 方法
    Python File read() 方法
    Python File next() 方法
    Python File isatty() 方法
    POJ 3281 Dining(最大流板子)
    poj 3436 ACM Computer Factory 最大流+记录路径
    HDU2732 Leapin' Lizards 最大流
    线段覆盖、区间选点、区间覆盖贪心讲解
    顺序表完成教师职称管理系统
    c++派生类中构造函数和析构函数执行顺序、判断对象类型、抽象类、虚函数
  • 原文地址:https://www.cnblogs.com/skywang12345/p/3095074.html
Copyright © 2011-2022 走看看