本文共 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 ++的背景将很有用。
To use NDK tools, ensure that the following two highlighted tools are downloaded from the SDK Manager:
要使用NDK工具,请确保从SDK Manager下载了以下两个突出显示的工具:
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_
.
我们在包名称前加上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中的等效类型:
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应用程序。
我们将介绍:First, create a new project and select C++ type template to integrate JNI in the application.
首先,创建一个新项目,然后选择C ++类型模板以将JNI集成到应用程序中。
Next, select the C++ compiler from the next screen.
接下来,从下一个屏幕中选择C ++编译器。
Let’s see how our project structure looks in the next section.
在下一部分中,让我们看看我们的项目结构如何。
CMake
to compile C and C++ code into a native library that the IDE then packages into your APK. CMake
将C和C ++代码编译到本机库中,然后IDE会将其打包到您的APK中。 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方法。 但是使用后需要释放。
The output when the above application was run is given below:
运行上述应用程序时的输出如下:
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/