zoukankan      html  css  js  c++  java
  • NDK---使用,开发步骤

    使用NDk的场景:

    1.某些方法,是使用C,C++本地代码实现的,然后,我想在Java中调用这些方法。这个时候,就需要使用到JNI技术。

    应用NDK的时候,分两个部分,Java部分,JNI层部分,本地代码部分。

    Java部分,看一个例子:

    public class JNIActivity extends Activity {
      
      static{
        
        System.loadLibrary("myjni");
      }
      
      public native String getMessage();
      
      
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        TextView textView = new TextView(this);
        textView.setText(getMessage());
        
        setContentView(textView);
      }
    
    
      @Override
      public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.jni, menu);
        return true;
      }
    
      @Override
      public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
          return true;
        }
        return super.onOptionsItemSelected(item);
      }
    }

    Java部分,要做的事情就是:1.声明要使用的本地方法,使用关键字native。2.加载包含实现该方法的库(在windows平台下是dll;在类Unix平台下是.so)。

    JNI层部分,则应用了JNI部分的知识,比如:

    #include <jni.h>
    #include "include/HelloJNI.h"
    
    JNIEXPORT jstring JNICALL Java_com_mytest_JNIActivity_getMessage
              (JNIEnv *env, jobject thisObj) {
       return (*env)->NewStringUTF(env, "Hello from native code!");
    }

    用一个简单的例子说明NDK的开发步骤:

    1.一个使用本地方法的Java类JNIActivity,声明使用C,C++代码实现的本地方法使用native关键字;载入动态库,此时动态库还没有生成。

    结果如下:

    public class JNIActivity extends Activity {
      
      static{
        
        System.loadLibrary("myjni");
      }
      
      public native String getMessage();
      
      
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        TextView textView = new TextView(this);
        textView.setText(getMessage());
        
        setContentView(textView);
      }
    
    
      @Override
      public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.jni, menu);
        return true;
      }
    
      @Override
      public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
          return true;
        }
        return super.onOptionsItemSelected(item);
      }
    }
    View Code

    2.在项目一级目录下创建jni文件夹;在jni文件夹下创建include文件夹。include文件夹,用来存放头文件。

    3.使用javah生成头文件---静态函数注册,将java层调用的本地方法与JNI层实现的方法进行关联

    在src目录下,使用命令:javah com.mytest.JNIActivity。

    类JNIActivity.java使用了原生方法;JNIActivity.java存放在src目录下。

    使用上述命令之后,在src目录下会有一个头文件:com_mytest_JNIActivity.h。

    将该头文件,复制到jni/include目录下,修改名字为HelloJNI.h。

    HelloJNI.h的内容:

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class com_mytest_JNIActivity */
    
    #ifndef _Included_com_mytest_JNIActivity
    #define _Included_com_mytest_JNIActivity
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     com_mytest_JNIActivity
     * Method:    getMessage
     * Signature: ()Ljava/lang/String;
     */
    JNIEXPORT jstring JNICALL Java_com_mytest_JNIActivity_getMessage
      (JNIEnv *, jobject);
    
    #ifdef __cplusplus
    }
    #endif
    #endif

    4.创建原生代码

    用原生代码实现头文件(HelloJNI.h)中所声明的方法。创建HelloJNI.c,存放在jni目录下。

    HelloJNI.c:

    #include <jni.h>
    #include "include/HelloJNI.h"
    
    JNIEXPORT jstring JNICALL Java_com_mytest_JNIActivity_getMessage
              (JNIEnv *env, jobject thisObj) {
       return (*env)->NewStringUTF(env, "Hello from native code!");
    }

    5.创建Android.mk

    Android.mk文件,描述编译信息。

    创建一个Android.mk文件,存放在jni目录下

    Android.mk:

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

    其中myjni,是一个动态库名称,它来自于java层代码,System.loadLibrary("myjni");。这个名字要与Java层中加载的动态库名称相同。

    HelloJNI.c,是实现原生方法的源代码。

    有关Android.mk更详细的内容,请参看Android官方文档。

    6.编译

    确保已经安装了NDK;并且把ndk-build对应的路径添加到系统的Path变量中。

    在项目的一级目录,执行命令ndk-build。

    如下:

    这样就编译成功了。

    7.运行

    运行App。

    总结:

    NDK的使用中,关键就是,创建头文件,编写Android.mk。在实现原生方法的时候,就是应用JNI方面的知识了。

  • 相关阅读:
    车标知识学习网页开发,与Flask通过base64展示二进制图片 #华为云·寻找黑马程序员#
    大型情感剧集Selenium:3_元素定位 #华为云·寻找黑马程序员#
    大型情感剧集Selenium:2_options设置 #华为云·寻找黑马程序员#
    【nodejs原理&源码赏析(9)】用node-ssh实现轻量级自动化部署
    大型情感剧集Selenium:1_介绍 #华为云·寻找黑马程序员#
    使用Python开发小说下载器,不再为下载小说而发愁 #华为云·寻找黑马程序员#
    #华为云·寻找黑马程序员#【代码重构之路】如何“消除”if/else
    #华为云·寻找黑马程序员#【代码重构之路】如何优雅的关闭外部资源
    走近深度学习,认识MoXing:初识华为云ModelArts的王牌利器 — MoXing
    开启 J2EE(一)—‘全明星队伍’
  • 原文地址:https://www.cnblogs.com/ttylinux/p/4001060.html
Copyright © 2011-2022 走看看