directory

  • preface
  • Configure the NDK environment
  • Download the NDK
  • Configure the NDK path
  • Configure the NDK environment path
  • The NDK to fit
  • Implement C function, and compile to generate.so
  • Other projects use.so
  • The last

preface

My AndroidStudio version is 2.3.3 and I haven’t updated it to 3.x(manual grievations). I want to finish my project before jumping into the pit. This time, I added the MAC configuration, but it’s not that different. Of course, Linux is pretty much the same, because Android Studio is universal. Why use.so? From my own understanding, there are several key points:

  • You don’t always develop alone, and your partners won’t be able to compile all the source code for you. So one solution would be for him to compile a dot so and give it to you, and then give you a dot h file that tells you what the functions are. For these functions, you only need to know the functionality, not the implementation details.
  • So files are compiled by C/CPP, the importance of C/CPP language is self-evident, the historical position is also unshakeable, and some had written libraries, there is no need to say because to write Android to change to Java to implement again. So you need Android to support those libraries that already exist.
  • Java source code decompilation is very easy to get, of course, can reinforce APK, will be a little better. After compiling.so, the source code for C is hard to see.

Configure the NDK environment

There is a headache called matching environment

Download the NDK

Configure the NDK path

Configure NDK environment variables

  • MAC: open.bash_profile with vim and add the NDK path at the end.
vim .bash_profile
Copy the code

Update the configuration file and test the NDK-build directive

  • win:

Open PowerShell to test it out

Finally, you can start using the NDK, or JNI if you like


The NDK to fit

  • Create the HellJNI class in the package directory and write the necessary code

Public class HelloJNI {// a public native int AddC (int a, int b); Static {// loadLibrary, pay attention to the consistency of library name system.loadlibrary ("HelloC"); }}Copy the code

Generate the header file using the Javah command. That’s the point. Recite it! Then create a new C/CPP with the same name.

  • mac:

  • win:


Implement C function, and compile to generate.so

  • Copy the function generated in the.h file and implement it in C/CPP.
/*
 * Class:     com_so_myapplication_HelloJNI
 * Method:    AddC
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_so_myapplication_HelloJNI_AddC
  (JNIEnv *, jobject, jint, jint);
Copy the code
#include "com_so_myapplication_HelloJNI.h"

JNIEXPORT jint JNICALL Java_com_so_myapplication_HelloJNI_AddC
  (JNIEnv * env, jobject obj, jint a, jint b){
    return a + b;
  }
Copy the code

Create android. mk and application. mk files in jni directory and write contents. The Android. Mk content is as follows:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE := HelloC
LOCAL_SRC_FILES := com_so_myapplication_HelloJNI.c
LOCAL_SRC_FILES += util.c

include $(BUILD_SHARED_LIBRARY)
Copy the code

There are two main points:

  • The LOCAL_MODULE name must be the same as beforeSystem.loadLibrary("HelloC");The same name in;
  • I need to add an empty one in Winutil.cFile to compile, otherwise will report an error, do not believe you can try (manual funny), MAC/Linux under no need. Application.mk contents are as follows:
APP_ABI := all
#APP_ABI := armeabi armeabi-v7a x86 mips arm64-v8a mips64 x86_64
Copy the code

There are two main points:

  • I know it’s unprofessional, but there are too many ABI issues to go into detail, mostly related to different cpus.
  • Armeabi seems to have been phased out. Build. Gradle. Build. Gradle:
android {
    compileSdkVersion 26
    buildToolsVersion "26.0.3"
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }
    defaultConfig {
        applicationId "com.so.myapplication"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        ndk {
            moduleName "HelloC" //System.loadLibrary("HelloC");
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}}Copy the code

NDK needs to be configured, pay attention to name match!

ndk {
    moduleName "HelloC" //System.loadLibrary("HelloC");
}
Copy the code

SourceSets configuration

sourceSets {
    main {
        jniLibs.srcDirs = ['libs']}}Copy the code

Add a sentence to gradle.properties

android.useDeprecatedNdk=true
Copy the code

Then the ndK-build is created, and then check to see if the build is successful!

You can use the addition function implemented by C in this project, but we have a cooler thing to do, which is to use this function in another project __.


Other projects use.so

It’s not so hard, basically two steps. The first step is to copy everything in the libs directory generated by the previous project into the libs directory that comes with AndroidStudio

The second step is to create the same package and class as the previous project that generated the liBS directory, and write the same content to the class. Add build. Gradle sourceSets to build. Gradle sourceSets to build.

public class HelloJNI {
    public native int AddC (int a, int b);
    static {
        System.loadLibrary("HelloC"); }}Copy the code
sourceSets {
    main {
        jniLibs.srcDirs = ['libs']}}Copy the code

Finally test the effect, this code I will not explain, this do not understand also farewell watch!

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView tv_testc = (TextView) findViewById(R.id.tv_testc);
        tv_testc.setText("add: "+ new HelloJNI().AddC(1, 2)); }}Copy the code


The last

End loose flower! Please remember to like me or follow me. If you have any questions or comments, please feel free to comment in the comments section