Simple example of Android Studio compiling so dynamic library

Simple example of compiling so dynamic library.

Although this example is simple, it has to be said that it still took a long time to work on and there will be many pitfalls. Although this is not the first time I have come into contact with JNI, this time is the most impressive one. You can also use your hands to deepen your memory. If there is anything wrong, please correct me~

You can use ndk-build and cmake to compile the so library in Android Studio. You can also use cygwin (window to simulate Linux environment) to compile the so library.

1. Configure the NDK environment

  • Download NDK through Android Studio SDKManager, select ndk and click OK to download.

 

figure 1

  • Manually download ndk at https://developer.android.google.cn/ndk/downloads/ and download the corresponding version according to your computer. If the URL is incorrect, search "NDK download" on Baidu. Unzip the downloaded compressed package, open "Project Structure" in the project, and select the NDK location as the directory where the NDK has been decompressed, as shown in Figure 4. The NDK environment configuration is OK.

 

 figure 2

 

image 3

 

Figure 4

 

 

2. Create a new project, JNIDemo, and configure the NDK of the project as above, otherwise it will prompt that the NDK of the project is not configured. Create a java class, JniTest, with the following content:

package com.example.jnidemo;

public class JniTest {
    static {
        System.loadLibrary("JniTest");
    }

    public native String jniHelloWorld();
}

 

 

 

Figure 5

 

3. Rebuild the project and check whether JniTest.java has generated the JniTest.class file. I use Android studio3.0 to check the following directory, app/build/intermediates/javac/debug/compileDebugJavaWithJavac/classes/com/example/jnidemo/JniTest. class, as shown in Figure 6. Other versions of studio may be in this directory.

“JNIDemo/app/build/intermediates/classes/debug/com/example/jnidemo/JniTest.class”.

 

 

Figure 6

 

4. Use javah to generate the .h file.

  • Open Terminal.
  • Open the directory to app\src\main, as shown in Figure 7.

 

 

Figure 7

  • Use the absolute directory of JniTest.class generated by the command javah -d jni -classpath to generate the .h file.

Obtain the upper-level directory of the absolute path of JniTest.class, and type in the final package name and class name, as shown in Figure 8.

The complete command (note that there are spaces after classes), as shown in Figure 9:

“javah -d jni -classpath D:\workplace\JNIDemo\app\build\intermediates\javac\debug\compileDebugJavaWithJavac

\classes com.example.jnidemo.JniTest”

Note: The generated jni folder and java folder must be at the same directory level, otherwise the so file will not be generated. The generated .h file and directory structure are shown in Figure 10. The content of the .h file is shown in Figure 11.

 

Figure 8

Figure 9

 

Figure 10

 

Figure 11

5. Write a .c file.

Include the .h file through "#include "com_example_jnidemo_JniTest.h" ".

Implement the methods in the header file, as shown in Figure 12. The content is as follows:

//
// Created by Lee on 2019/2/17.
//
#include "com_example_jnidemo_JniTest.h"
JNIEXPORT jstring JNICALL Java_com_example_jnidemo_JniTest

_jniHelloWorld
  (JNIEnv *env, jobject obj){
        return (*env)->NewStringUTF(env,"JNI helloworld");
  }

 

Figure 12

6. Rebuild the project and run it. The following error appears, as shown in Figure 13:

 Figure 13

Add android.useDeprecatedNdk=true to the project's gradle.properties, as shown in Figure 15.

 

Figure 14

 Figure 15

New error occurred:

Error: Flag android.useDeprecatedNdk is no longer supported and will be removed in the next version of Android Studio. Please switch to a supported build system.

Consider using CMake or ndk-build integration. For more information, go to:

https://d.android.com/r/studio-ui/add-native-code.html#ndkCompile

To get started, you can use the sample ndk-build script the Android

plugin generated for you at:

D:\workplace\JNIDemo\app\build\intermediates\ndk\debug\Android.mk

Alternatively, you can use the experimental plugin:

https://developer.android.com/r/tools/experimental-plugin.html

To continue using the deprecated NDK compile for another 60 days, set

android.deprecatedNdkCompileLease=1550382670665 in gradle.properties

 

Figure 16

The general meaning is that android.useDeprecatedNdk=true will no longer be supported in the near future, and may be removed in the next Android studio. You can use CMake or ndk-build. Or use android.deprecatedNdkCompileLease=1550382670665 to continue using it for 60 days.

 

So you can use android.deprecatedNdkCompileLease=1550382670665 instead of android.useDeprecatedNdk=true. For the rebuilde project, the so dynamic library will be obtained in the ndk directory under the intermediates directory. Cmake will also be used to solve the problem below.

 

How to use Cmake:

  • Download Cmake and LLDB directly from sdkmanager. As shown in Figure 17. It can also be downloaded from Baidu and can be used after configuring the environment variables.

Figure 17

 

  • Add the following under the defaultConfig tag in the app's build.gradle file:
externalNativeBuild {
    cmake {
        cppFlags ""
        //生成多个版本的so文件
        abiFilters 'arm64-v8a', 'armeabi-v7a','x86'
    }
}

Add under the android tag:

externalNativeBuild{
    cmake{
        path "CMakeLists.txt"
    }
}

CMakeLists.txt is used to set the C source code file to be compiled and the file name of the compiled so library.

  • Add CMakeLists.txt to the app directory (note: it must be at the same level as the build.gradle file in the app directory, otherwise problems will occur. I was stuck for a long time because I put it in the wrong directory). The content of the CMakeLists.txt file is as follows, as shown in the figure 18, Figure 19:

 

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.
#CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

add_library( # Sets the name of the library.
      # 设置so文件名称.
       JniTest

       # Sets the library as a shared library.
       SHARED
       # 设置这个so文件为共享.

       # Provides a relative path to your source file(s).
       # 要编译的文件
       src/main/jni/main.c)

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
       log-lib

       # Specifies the name of the NDK library that
       # you want CMake to locate.
       log )

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
            # 制定目标库.
            JniTest

            # Links the target library to the log library
            # included in the NDK.
            ${log-lib} )

 

 

 Figure 18

 Figure 19

  • When rebuilding the project, the so dynamic library appears, as shown in Figure 20.

 

Figure 20

  • Run the project

 

Guess you like

Origin blog.csdn.net/health7788/article/details/87532920