博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
jni ndk_带有NDK的Android JNI应用程序
阅读量:2531 次
发布时间:2019-05-11

本文共 8532 字,大约阅读时间需要 28 分钟。

jni ndk

In this tutorial, we’ll be discussing JNI and develop a basic Android Application using NDK tools. A background in c/c++ would be useful, though not a prerequisite.

在本教程中,我们将讨论JNI并使用NDK工具开发基本的Android应用程序。 尽管不是前提条件,但使用c / c ++的背景将很有用。

Android NDK is a companion tool of Android SDK that allows us to use native code C/C++ in our development.
Android NDK是Android SDK的配套工具,可让我们在开发中使用本机代码C / C ++。

To use NDK tools, ensure that the following two highlighted tools are downloaded from the SDK Manager:

要使用NDK工具,请确保从SDK Manager下载了以下两个突出显示的工具:

Android Jni Ndk Setup

Android Jni Ndk Setup

Android Jni Ndk安装

什么是JNI? (What is JNI?)

JNI stands for Java Native Interface. It acts as a bridge through which the Java/Kotlin code can call native code and vice-versa.

Moreover, JNI is needed typically in games since most of the engines are built using c/c++.

JNI代表Java本机接口。 它充当Java / Kotlin代码可以调用本机代码的桥梁,反之亦然。

此外,游戏中通常需要JNI,因为大多数引擎都是使用c / c ++构建的。

In order to call a native method in Java, you need to first define it in the Java code using the native keyword.

为了在Java中调用本机方法,您需要首先使用native关键字在Java代码中定义它。

Example:

public native String stringFromJNI()
The native keyword transforms the method into an abstract method which we need to implement in our shared library in c/c++.

例:

public native String stringFromJNI()
native关键字将方法转换为抽象方法,我们需要在c / c ++的共享库中实现该方法。

To define the method in c/c++ we need to use the following signature:

要在c / c ++中定义方法,我们需要使用以下签名:

extern "C" JNIEXPORT jstring JNICALLJava_com_journaldev_androidjnibasics_MainActivity_stringFromJNI(JNIEnv* env,jobject)

We prepend the package name with Java_.

And the package name is followed by the Activity name without the extension and the native method name.

我们在包名称前加上Java_

程序包名称后跟活动名称(不带扩展名)和本机方法名称。

JNIEXPORT– marks the function into the shared lib as exportable so it will be included in the function table, and thus JNI can find it

JNICALL – combined with JNIEXPORT, it ensures that our methods are available for the JNI framework.

JNIEXPORT –将函数标记为共享库中的可导出函数,因此它将包含在函数表中,因此JNI可以找到它

JNICALL –与JNIEXPORT结合使用,可确保我们的方法可用于JNI框架。

The JNIEnv is the most important component of the JNI space. It acts as a bridge to access the Java objects.

JNIEnv是JNI空间中最重要的组件。 它充当访问Java对象的桥梁。

JNI types and there equivalent types in Java are given below:

下面给出了JNI类型以及Java中的等效类型:

  • boolean : jboolean

    布尔值:jboolean
  • byte : jbyte

    字节:jbyte
  • char : jchar

    字符:jchar
  • double : jdouble

    双重:jdouble
  • float : jfloat

    float:jfloat
  • int : jint

    int:jint
  • long : jlong

    long:jlong

To load the native library on startup add the following block in your code:

要在启动时加载本机库,请在代码中添加以下代码块:

static {        System.loadLibrary("native-lib");    }

“native-lib” is the name of the native file of c/c++.

“ native-lib”是c / c ++的本机文件的名称。

In the next section, we’ll be creating our JNI application in Android.

We’ll be covering:

在下一节中,我们将在Android中创建JNI应用程序。

我们将介绍:

  • How to get/send Strings for Java to native code.

    如何获取/发送Java字符串到本地代码。
  • View logs from native code in Android Studio Log console.

    在Android Studio日志控制台中从本机代码查看日志。
  • Get an array of strings from c++ in Java.

    从Java中的c ++获取字符串数组。

入门 (Getting Started)

First, create a new project and select C++ type template to integrate JNI in the application.

首先,创建一个新项目,然后选择C ++类型模板以将JNI集成到应用程序中。

Android Jni Project Setup 1

Android Jni Project Setup 1

Android Jni项目设置1

Next, select the C++ compiler from the next screen.

接下来,从下一个屏幕中选择C ++编译器。

Android Jni Project Setup 2

Android Jni Project Setup 2

Android Jni项目设置2

Let’s see how our project structure looks in the next section.

在下一部分中,让我们看看我们的项目结构如何。

项目结构 (Project Structure)

Android Jni Project Structure

Android Jni Project Structure

Android Jni项目结构

CMake to compile C and C++ code into a native library that the IDE then packages into your APK.
CMake将C和C ++代码编译到本机库中,然后IDE会将其打包到您的APK中。

(Code)

In the default setup, we have a native function that allows us to get a string from the native code in our Java code using JNI.

在默认设置中,我们有一个本机函数,该函数允许我们使用JNI从Java代码中的本机代码获取字符串。

Let’s improve upon the layout with two new buttons for more JNI functions that we’ll call.

让我们通过两个新按钮来改进布局,以使用更多JNI函数。

The code for the activity_main.xml layout is given below:

下面给出了activity_main.xml布局的代码:

The code for the MainActivity.java class is given below:

MainActivity.java类的代码如下:

package com.journaldev.androidjnibasics;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends AppCompatActivity {    // Used to load the 'native-lib' library on application startup.    static {        System.loadLibrary("native-lib");    }    Button btnJNI, btnJNIStringArray;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        // Example of a call to a native method        TextView tv = findViewById(R.id.sample_text);        tv.setText(stringFromJNI());        btnJNI = findViewById(R.id.btnJni);        btnJNIStringArray = findViewById(R.id.btnJniStringArray);        btnJNI.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                String result = sendYourName("Anupam", "Chugh");                Toast.makeText(getApplicationContext(), "Result from JNI is " + result, Toast.LENGTH_LONG).show();            }        });        btnJNIStringArray.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                String[] strings = stringArrayFromJNI();                Toast.makeText(getApplicationContext(), "First element is "+strings[0], Toast.LENGTH_LONG).show();            }        });    }    /**     * A native method that is implemented by the 'native-lib' native library,     * which is packaged with this application.     */    public native String stringFromJNI();    public native String sendYourName(String firstName, String lastName);    public native String[] stringArrayFromJNI();    }

We’ve defined three native methods – string, computing strings in native code and returning, returning string array.

我们定义了三种本机方法–字符串,用本机代码计算字符串以及返回,返回字符串数组。

Let’s dig into the native-lib.cpp file which contains the functions defined in C++:

让我们深入研究native-lib.cpp文件,其中包含C ++中定义的功能:

#include       #include          #include            #include              extern "C" JNIEXPORT jstring JNICALLJava_com_journaldev_androidjnibasics_MainActivity_stringFromJNI(        JNIEnv* env,        jobject /* this */) {    std::string hello = "Hello from C++";    __android_log_write(ANDROID_LOG_DEBUG, "API123", "Debug Log");    return env->NewStringUTF(hello.c_str());}extern "C" JNIEXPORT jstring JNICALLJava_com_journaldev_androidjnibasics_MainActivity_sendYourName(        JNIEnv* env,        jobject, jstring firstName, jstring lastName) {    char returnString[20];    const char *fN = env->GetStringUTFChars(firstName, NULL);    const char *lN = env->GetStringUTFChars(lastName, NULL);    strcpy(returnString,fN); // copy string one into the result.    strcat(returnString,lN); // append string two to the result.    env->ReleaseStringUTFChars(firstName, fN);    env->ReleaseStringUTFChars(lastName, lN);    __android_log_write(ANDROID_LOG_DEBUG, "API123", returnString);    return env->NewStringUTF(returnString);}extern "C"JNIEXPORT jobjectArray JNICALL Java_com_journaldev_androidjnibasics_MainActivity_stringArrayFromJNI(JNIEnv *env, jobject jobj){    char *days[]={"Java",                  "Android",                  "Django",                  "SQL",                  "Swift",                  "Kotlin",                  "Springs"};    jstring str;    jobjectArray day = 0;    jsize len = 7;    int i;    day = env->NewObjectArray(len,env->FindClass("java/lang/String"),0);    for(i=0;i<7;i++)    {        str = env->NewStringUTF(days[i]);        env->SetObjectArrayElement(day,i,str);    }    return day;}

To convert from JNI strings to a native char array, you can use the GetStringUTFChars method of the env. But it needs to be released after use.

要将JNI字符串转换为本地char数组,可以使用env的GetStringUTFChars方法。 但是使用后需要释放。

android_log_write is used to log the statements in the Android console.
android_log_write用于在Android控制台中记录语句。

The output when the above application was run is given below:

运行上述应用程序时的输出如下:

Android Jni Output

Android Jni Output

Android Jni输出

This brings an end to this tutorial. You can download the project from the link below or view the full source code in our Github Repository.

本教程到此结束。 您可以从下面的链接下载项目,或者在我们的Github存储库中查看完整的源代码。

翻译自:

jni ndk

转载地址:http://knlzd.baihongyu.com/

你可能感兴趣的文章
Jenkins安装配置
查看>>
个人工作总结05(第二阶段)
查看>>
Java clone() 浅拷贝 深拷贝
查看>>
深入理解Java虚拟机&运行时数据区
查看>>
02-环境搭建
查看>>
spring第二冲刺阶段第七天
查看>>
搜索框键盘抬起事件2
查看>>
阿里百川SDK初始化失败 错误码是203
查看>>
透析Java本质-谁创建了对象,this是什么
查看>>
BFS和DFS的java实现
查看>>
关于jquery中prev()和next()的用法
查看>>
一、 kettle开发、上线常见问题以及防错规范步骤
查看>>
eclipse没有server选项
查看>>
CRC码计算及校验原理的最通俗诠释
查看>>
使用Gitbook来编写你的Api文档
查看>>
jquery扩展 $.fn
查看>>
Markdown指南
查看>>
influxDB的安装和简单使用
查看>>
JPA框架学习
查看>>
JPA、JTA、XA相关索引
查看>>