First, we register a static jni function and write the following code in the entry java class:
static { System.loadLibrary("test"); }
Then the header file is generated with javah at the terminal. If the command is not found in the report, the environment variable is configured.
Find out where jdk is under mac, as shown in the figure:
Add environment variables
VIM ~/. bash_profile adds corresponding paths Source ~/.bash_profile update
java directory into src directory
Input: parameter https://blog.csdn.net/u011993368/article/details/46831819
javah -d jni com.example.haidragon.testcpp.MainActivity
Then put it in the jni directory, and write android.mk and function implementation in the jni directory.
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := test LOCAL_SRC_FILES := testJni.cpp include $(BUILD_SHARED_LIBRARY)
testJni.cpp
extern "C" JNIEXPORT jstring JNICALL Java_com_example_haidragon_testcpp_MainActivity_getStringFromNDK(JNIEnv *env, jclass type) { // TODO return env->NewStringUTF("Java_com_example_haidragon_test_testNDK_getStringFromNDK"); }
Modify gradle in app directory
Add (Source Network)
Run ok ay.
There are several interesting places.
The first jni can be put freely. Generally, it is in the same level directory of java on the internet, as shown in the figure:
The second header file is not required, but it must contain jni.h itself in the cpp and add extern "C"
//#include"com_example_haidragon_testcpp_testNDK.h" #include <jni.h> #include<stdio.h> #include<stdlib.h> JNIEXPORT jstring JNICALL Java_com_example_haidragon_testcpp_testNDK_getStringFromNDK( JNIEnv *env, jobject /* this */) { //const char* hello = "Java_com_example_haidragon_test_testNDK_getStringFromNDK"; return env->NewStringUTF("Java_com_example_haidragon_test_testNDK_getStringFromNDK"); } //void __attribute__ ((constructor)) SoMain(int argc, char *argv[]){ // FILE * pFile; // Define a pointer to a file type // char mystring[400]; // Defines a data to store data read from a file // int i; // char s = ','; // pFile= fopen("/data/local/tmp/test.txt", "a+"); // for (i = 0; i < 10;i++) // { // printf("/data/local/test\n"); // fprintf(pFile,"%d", i); // Write "i" // fprintf(pFile,"%c", s); // Write ". // } // fclose(pFile); //End //} int main(int argc, char *argv[]) { FILE * pFile;//Pointer defining a file type char mystring[400];//Define a data to store data read from a file int i; char s = ','; pFile= fopen("/data/local/tmp/test.txt", "a+"); for (i = 0; i < 10;i++) { printf("/data/local/test\n"); fprintf(pFile,"%d", i); //Write "i" fprintf(pFile,"%c", s); //Write "." } fclose(pFile); //End return 0; } extern "C" JNIEXPORT jstring JNICALL Java_com_example_haidragon_testcpp_MainActivity_getStringFromNDK(JNIEnv *env, jclass type) { // TODO return env->NewStringUTF("Java_com_example_haidragon_test_testNDK_getStringFromNDK"); }
The loading point of the third library, where I create a new class and load it in front, runs incorrectly.
The fourth library name can't be the same as the file name. If you use the command line, you can compile it, but when you compile and run it with as, you run the same error.
The fifth can be empty so or nothing with this symbol normal logic
Sixth, but no constructor
All of these will result in the failure of operation.
The seventh must be the cpp file, which should be no problem.
Source code:
MainActivity.java
package com.example.haidragon.testcpp; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.TextView; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView tv =findViewById(R.id.testid); testNDK test=new testNDK(); tv.setText(getStringFromNDK()); } static { System.loadLibrary("test"); } public static native String getStringFromNDK(); }
testJni.cpp
//#include"com_example_haidragon_testcpp_testNDK.h" #include <jni.h> #include<stdio.h> #include<stdlib.h> JNIEXPORT jstring JNICALL Java_com_example_haidragon_testcpp_testNDK_getStringFromNDK( JNIEnv *env, jobject /* this */) { //const char* hello = "Java_com_example_haidragon_test_testNDK_getStringFromNDK"; return env->NewStringUTF("Java_com_example_haidragon_test_testNDK_getStringFromNDK"); } void __attribute__ ((constructor)) SoMain(int argc, char *argv[]){ FILE * pFile;//Pointer defining a file type char mystring[400];//Define a data to store data read from a file int i; char s = ','; pFile= fopen("/data/local/tmp/test.txt", "a+"); for (i = 0; i < 10;i++) { printf("/data/local/test\n"); fprintf(pFile,"%d", i); //Write "i" fprintf(pFile,"%c", s); //Write "." } fclose(pFile); //End } int main(int argc, char *argv[]) { FILE * pFile;//Pointer defining a file type char mystring[400];//Define a data to store data read from a file int i; char s = ','; pFile= fopen("/data/local/tmp/test.txt", "a+"); for (i = 0; i < 10;i++) { printf("/data/local/test\n"); fprintf(pFile,"%d", i); //Write "i" fprintf(pFile,"%c", s); //Write "." } fclose(pFile); //End return 0; } extern "C" JNIEXPORT jstring JNICALL Java_com_example_haidragon_testcpp_MainActivity_getStringFromNDK(JNIEnv *env, jclass type) { // TODO return env->NewStringUTF("Java_com_example_haidragon_test_testNDK_getStringFromNDK"); }
Android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := test LOCAL_SRC_FILES := testJni.cpp include $(BUILD_SHARED_LIBRARY)
app/build.gradle
apply plugin: 'com.android.application' android { compileSdkVersion 28 defaultConfig { applicationId "com.example.haidragon.testcpp" minSdkVersion 19 targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" ndk{ moduleName "test" abiFilters "armeabi-v7a", "arm64-v8a", "x86", "x86_64" } } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } externalNativeBuild { ndkBuild { path 'src/main/java/jni/Android.mk' } } sourceSets.main { jni.srcDirs = [] jniLibs.srcDirs = ['src/main/java/jniLibs'] } } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' }