14

The native code native.c

#include <string.h>
#include <stdio.h>
#include <jni.h>

jstring Java_com_lab5_oli_myapplication_MainActivity_helloWorld(JNIEnv* env,jobject obj)
{
    return (*env)->NewStringUTF(env,"Hello world");
}

Android.mk file

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE:=ocrex
LOCAL_SRC_FILES:=ndkTest.c

include $(BUILD_SHARED_LIBRARY)

Application.mk file

APP_ABI := all

code in MainActivity

public native String helloWorld();
static{
    System.loadLibrary("ocrex");
}

The method is recognised to be declared in the native code(note on side bar)

olmnt
  • 157
  • 1
  • 1
  • 6
  • Where's your `JNI_OnLoad()` function? And what about your function table for c to java mapping? If this is your entire code then you are missing quite a few pieces. I suggest you grab a book about Android and JNI. – Chef Pharaoh Apr 10 '18 at 13:31

1 Answers1

7

First if you are using android studio 2.2 and above use Cmake because Android Studio's default build tool for native libraries is CMake. But if you need the ndk-build android studio still supports the ndk-build.

1) Add JNIEXPOT and JNICALL into the native method and make sure the com_lab5_oli_myapplication is the package name of the MainActivity class.

#include <string.h>
#include <stdio.h>
#include <jni.h>

JNIEXPORT jstring  JNICALL Java_com_lab5_oli_myapplication_MainActivity_helloWorld(JNIEnv* env,jobject obj)
{
    return (*env)->NewStringUTF(env,"Hello world");
}

2) And in the Android.mk file change the source name your c++ name is native.c but in the Android.mk file you used ndkTest.c file name.

LOCAL_SRC_FILES:=ndkTest.c
//change it to 
LOCAL_SRC_FILES:=native.c

Finally you have to link the gradle into native library. 1) If you have android studio 2.2 and above right click on the app and there is Link c++ project with gradle. If you are using ndk-build then choose the Android.mk file if you are using Cmake build choose the insert the address of the CmakeLists. 2) You can also manually configure gradle to include the native library.You need to add the externalNativeBuild block to your module-level build.gradle file and configure it with either the cmake or ndkBuild block: If you are using cmake

 externalNativeBuild {

    // Encapsulates your CMake build configurations.
    cmake {

      // Provides a relative path to your CMake build script.
      path "CMakeLists.txt"
    }
  }

And if you are using ndk-build

externalNativeBuild {

    // Encapsulates your CMake build configurations.
    ndkBuild {

      // Provides a relative path to your to the Android.mk build script.
      path "Android.mk"
    }
  }

For detail information about cmake and ndk in android use this and this.

Yirga
  • 881
  • 1
  • 12
  • 31
  • still error with the same problem. android studio says can not resolve. and I run into a crash with no implementation found for that jni function call. I check my folder, it did compile a .so file. – flankechen Aug 04 '17 at 02:55
  • Are you using Cmake or NDK-build? – Yirga Aug 04 '17 at 13:51
  • 6
    NDK-build. I solved my problem. jni export functio name not match with package name because of refactoring the interface java class. Thanks a lot. – flankechen Aug 08 '17 at 06:24
  • For new projects Google recommend Cmake. CMake is a more effective way to build C/C++ code due to its mature syntax. https://developer.android.com/ndk/guides/cmake.html – Yirga Aug 08 '17 at 08:32
  • well, is there a translator from ndk to cmake? I am working with library(OpenCV) in android where no cmake example is provided. – flankechen Aug 09 '17 at 02:02
  • you don't need a translator it is easy to use cmake use this https://stackoverflow.com/questions/41164593/add-opencv-in-cmakelists-txt-android/42962877#42962877 or follow instruction https://developer.android.com/studio/projects/add-native-code.html – Yirga Aug 09 '17 at 07:43