美文网首页
Java语言如何与本地代码(C/C++)交互

Java语言如何与本地代码(C/C++)交互

作者: baby_double | 来源:发表于2017-12-25 10:46 被阅读0次
注意: 写该文章主要帮助自己记忆,贴出来希望可以给有同样问题的人解惑,不喜勿喷,可以提意见哦。

一、需要了解的知识点:
(1)NDK:允许Java的代码与其他语言的代码进行交互的开发包
(2)jni:java与本地代码(c/c++)通过jni交互
(3)常见使用NDK的平台,TV——电视机,STB——机顶盒,IVI——车载系统,AR——虚拟现实,手机端游戏等。

二、为什么需要NDK
(1)标准的Java虚拟机不支持应用需要的平台相关的功能,例如添加了新的硬件设备。
(2)已经存在使用C/C++等其他语言开发好的库,需要使用JNI来访问他们,例如游戏引擎Cocos2d-X
(3)需要优化其中一部分的源代码,提升整体性能。

三、搭建开发环境
(1)Windows开发环境搭建
首先在http://developer.android.com/tools/sdk/ndk/index.html下载ndk
http://www.cygwin.com下载Cygwin1.7并安装,Cygwin1.7安装需要注意如下两个地方,选择make和vim,只用勾选红框中的的内容。

1511769566(1).png 1511769642(1).png

四、在开发工具eclipse上使用NDK,实现一个简单的减法操作,目的是学会Java与本地代码的交互。
(1)首先需要在Java代码中声明一个本地方法sub()。

package com.example.main;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends Activity {

//static{
//  System.loadLibrary("main");
//}
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

private native int sub(int a,int b); //关键字native表示该方法需要在本地代码中实现
}

(2)使用NDK用C/C++实现add方法

1、打开之前安装的Cygwin, 输入命令cd e: 进入如下目录cygdrive,进入该目录是本机的cygwin装在了e目录。注意,一定要进入cygdrive目录,然后在该目录下进入不同的目录。


1511770670(1).png

2、进入x项目Main所在的目录,例如:D:\lcb\work\Main,输入如下命令:


1511771041(1).png
3、利用ndk生成Main.java的头文件,进入src目录,输入命令javah -d ../jni com.example.main.MainActivity。javah表示生成头文件的命令,-d 表示生成到指定的目录,../jni 表示src的上一个目录,即main目录下生成文件夹jni, com.example.main.MainActivity 表示生成MainActivity的头文件。
Administrator@MS-20170524EUSY /cygdrive/d/lcb/work/Main/src
$ javah -d ../jni com.example.main.MainActivity
在工作目录下对应生成了jni目录,如下所示: 1511771532(1).png

4、生成头文件内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h> 
/* Header for class com_example_main_MainActivity */

#ifndef _Included_com_example_main_MainActivity
#define _Included_com_example_main_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
  * Class:     com_example_main_MainActivity
  * Method:    sub
  * Signature: (II)I
*/
 //Java关键字+类所在的包名+类名+方法名。.换成下划线。
JNIEXPORT jint JNICALL Java_com_example_main_MainActivity_sub
  (JNIEnv *, jobject, jint, jint);

 #ifdef __cplusplus
}
#endif
#endif

5、创建本地方法sub.c,可以直接在本地创建一个文件,命名为sub.c,方法名需要跟头文件中生成的对应。

#include "com_example_main_MainActivity.h"  //这里引用4生成的头文件
JNIEXPORT jint JNICALL Java_com_example_main_MainActivity_sub(JNIEnv *evn,
    jobject object, jint a, jint b) {
return a - b;}

6、创建Android.mk编译文件。

LOCAL_PATH:= $(call my-dir)
 //$(call my-dir),指带本应用的D:\lcb\work\Main\jni目录
include $(CLEAR_VARS)
 //清除前面所定义的变量
LOCAL_MODULE    :=main
//这里main指java语言中加载的so库名字
LOCAL_SRC_FILES := sub.c
//当前需要编译的本地代码名称
include $(BUILD_SHARED_LIBRARY)
//表示需要编译一个动态库

7、编译动态库
进入

Administrator@MS-20170524EUSY /cygdrive/d/lcb/work/Main/jni目录,执行如下命令:ndk-build.cmd

命令执行完毕后,在lib目录下就会对应生成so文件,如下所示:

1511773418(1).png

8、在java代码中加载so库文件,到这里就完成了java代码使用本地代码的全过程。

package com.example.main;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends Activity {

static{
    System.loadLibrary("main");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

private native int sub(int a,int b);
}

四、在开发工具Android Studio上使用NDK,实现一个简单的加法操作,目的是学会Java与本地代码的交互。
1、首先进入Project Structure目录下的SDK Location,如下所示,在红框中引用已经下载好的ndk。


1511851575(1).png

2、在Java代码中声明一个本地方法add()

package com.hwatong.meidaplayer;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class USBMediaPlayer extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

private native int add(int a,int b);
}

3、打开android Studio的控制台,进入项目所在的目录,输入编译头文件的命令,编译后就会生成对应的目录。

E:\USBMusicPlayer_a12_Activity\src>javah -d ../jni com.hwatong.meidaplayer.USBMediaPlayer
1511852554(1).png

4、创建add.c文件,如下所示

#include "com_hwatong_meidaplayer_USBMediaPlayer.h"
JNIEXPORT jint JNICALL 
Java_com_hwatong_meidaplayer_USBMediaPlayer_add
  (JNIEnv *, jobject, jint, jint){
   return a+b;
 }

5、创建Android.mk编译文件

LOCAL_PATH:= $(call my-dir)
 //$(call my-dir),指带本应用的D:\lcb\work\Main\jni目录
include $(CLEAR_VARS)
 //清除前面所定义的变量
LOCAL_MODULE    :=main
//这里main指java语言中加载的so库名字
LOCAL_SRC_FILES := add.c
//当前需要编译的本地代码名称
include $(BUILD_SHARED_LIBRARY)
//表示需要编译一个动态库

6、切换到控制台,进入jni目录,输入命令ndk-build,则会在lib目录生成对应的so库。

E:\USBMusicPlayer_a12_Activity\jni>ndk-build
[arm64-v8a] Compile        : main <= add.c
[arm64-v8a] SharedLibrary  : libmain.so
[arm64-v8a] Install        : libmain.so => libs/arm64-v8a/libmain.so
[x86_64] Compile        : main <= add.c
...
1511853239(1).png

7、在java代码中应用so库。

 package com.hwatong.meidaplayer;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class USBMediaPlayer extends Activity {

static{
  System.loadLibrary("main");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

private native int add(int a,int b);
}

相关文章

  • Android 添加JNI 开发能力

    JNI 与 NDK 区别JNI:JNI是一套编程接口,用来实现Java代码与本地的C/C++代码进行交互;NDK:...

  • Java语言如何与本地代码(C/C++)交互

    一、需要了解的知识点:(1)NDK:允许Java的代码与其他语言的代码进行交互的开发包(2)jni:java与本地...

  • NDK JNI--学习笔记

    JNI 是java语言提供的Java和C/C++相互沟通的机制,Java可以通过JNI调用本地的C/C++代码,...

  • Java Native Interface(JNI) 简介

    博客中提到的JNI均指Java Native Interface,Java本地接口。本地代码均指C/C++代码。 ...

  • CMakeList

    JNI(Java Native Interface):Java本地接口。是为了方便Java调用c、c++等本地代码...

  • JNI知识点总结

    JNI概念 JNI是本地语言编程接口。它允许运行在JVM中的Java代码和用C、C++或汇编写的本地代码相互操作。...

  • Led控制从内核到app的实现之jni层(三)

    JNI概念 JNI是本地语言编程接口。它允许运行在JVM中的Java代码和用C、C++或汇编写的本地代码相互操作。...

  • android jni和ndk

    JNI是Java Native Interface(Java本地接口),是为了方便Java调用C和C++等本地代码...

  • JNI 调用 JAVA 接口

    JNI 调用 JAVA 接口 介绍 JNI 是本地语言编程接口。它允许运行在JVM中的Java代码和用C、C++或...

  • Android JNI、NDK实现

    一、前言为什么要使用jni、ndk?效率上 C/C++是本地语言,比java更高效代码移植,如果之前用C语言开发过...

网友评论

      本文标题:Java语言如何与本地代码(C/C++)交互

      本文链接:https://www.haomeiwen.com/subject/pwcdbxtx.html