AndroidStudio中jni的使用

1.新建一个Jni调用类

public class MyJni {

    static {
        System.loadLibrary("MyJni");
//        System.load("/data/user/0/com.example.myapplication/app_libs/libMyJni.so");
//        System.load("/storage/emulated/0/Android/data/com.example.myapplication/download/libMyJni.so");
//        javah -jni -classpath E:\cdz\MyApplication2\app\build\intermediates\javac\debug\classes com.example.myapplication.MyJni
    }

    public native static String getString();



}

2.点击build-->make project

完成后会在app\build\intermediates\javac\debug\classes\com.example.myapplication\目录下生成一个MyJni.class文件

AndroidStudio中jni的使用_第1张图片

3.在main目录下新建一个jni文件夹

AndroidStudio中jni的使用_第2张图片

4.打开terminal:cd到jni目录下运行:

javah -jni -classpath E:\cdz\MyApplication2\app\build\intermediates\javac\debug\classes com.example.myapplication.MyJni

会在jni目录下生成一个com_example_myapplication_MyJni.h文件

AndroidStudio中jni的使用_第3张图片

5.新建一个test1.c文件

#include "jni.h"
#include "com_example_myapplication_MyJni.h"
#include 
#include 
#include 


JNIEXPORT jstring JNICALL Java_com_example_myapplication_MyJni_getString
  (JNIEnv *env, jclass jz){


       /*手动加载指定位置的so动态库*/
        void* handle = dlopen("/data/user/0/com.example.myapplication/app_libs/libMyAdd.so", RTLD_LAZY);


        if (handle)
        {
                      int (*add)(int a, int b);

                        /*根据动态链接库操作句柄与符号,返回符号对应的地址*/
                        add = dlsym(handle, "add");

                        int sum = add(7, 8);
                        printf("7+8 = %d\n", sum);

                        dlclose(handle);
                        return (*env)->NewStringUTF(env,"jni---->so---->so result=");
        }else{
                return (*env)->NewStringUTF(env, "open failed!");
        }




  }

6.新建一个Android.mk文件

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

LOCAL_MODULE := MyJni
LOCAL_SRC_FILES := test1.c
include $(BUILD_SHARED_LIBRARY)

7.新建一个Application.mk文件

APP_CPPFLAGS += -fpermissive #兼容老的语法,使一些错误降为警告
APP_ABI := all

8.打开terminal cd到jni目录下 运行ndk-build命令生成libMyJni.so库

AndroidStudio中jni的使用_第4张图片

9.新建一个test2.c文件文件 

int add( int x, int y)
{
     return x + y;
}

10.修改Android.mk文件

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

LOCAL_MODULE := MyAdd 
LOCAL_SRC_FILES := test2.c
include $(BUILD_SHARED_LIBRARY)

11.打开terminal cd到jni目录下 运行ndk-build命令生成libMyAdd.so库

AndroidStudio中jni的使用_第5张图片

12.在工程的build.gradle文件中加入

sourceSets {
        main() {
//            jniLibs.srcDirs = ['src/main/libs']
//            jni.srcDirs = [] //屏蔽掉默认的jni编译生成过程
            jniLibs.srcDirs =['libs']
        }
    }

AndroidStudio中jni的使用_第6张图片

 

13.将生成的libMyAdd.so文件复制到/data/user/0/com.example.myapplication/app_libs/目录下

String path = LoadSoFileUtils.loadLibrary1(MainActivity.this, "/storage/emulated/0/C60/lib", "libMyAdd.so");
if (path!=null&&!"".equals(path)) {
    LogUtils.e("so文件复制成功");
    Log.e("cdz","result="+MyJni.getString());
}
public static String loadLibrary1(Context context, String libPath, String libName) {
    File libs_dir = context.getDir("libs", Context.MODE_PRIVATE);

    String new_file_name = libs_dir.getPath() + "/" + libName;
    String old_file_name = libPath + "/" + libName;
    if (!copyLibrary(new_file_name, old_file_name)) {
        return "";
    }else {
        return new_file_name;
    }
}

private static boolean copyLibrary(String new_file_name, String old_file_name) {

    LogUtils.e("new file="+new_file_name);

    FileInputStream fis = null;
    FileOutputStream fos = null;
    try {
        File new_file = new File(new_file_name);
        File old_file = new File(old_file_name);

        if (new_file.exists()) new_file.delete();

        fis = new FileInputStream(old_file);
        fos = new FileOutputStream(new_file);

        int     dataSize;
        byte[]  dataBuffer = new byte[2048];

        while ((dataSize = fis.read(dataBuffer)) != -1) {
            fos.write(dataBuffer, 0, dataSize);
        }
        fos.flush();

        return true;
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (fos != null) fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            if (fis != null) fis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    return false;
}

14.将生成的libMyJni.so文件复制到app/libs目录下

AndroidStudio中jni的使用_第7张图片

 

15.调用libMyJni.so 由于libMyJni.so调用了libMyadd.so所以必须先复制libMyAdd.so到相应目录下才能调用libMyAdd.so

String path = LoadSoFileUtils.loadLibrary1(MainActivity.this, "/storage/emulated/0/C60/lib", "libMyAdd.so");
if (path!=null&&!"".equals(path)) {
    LogUtils.e("so文件复制成功");
    Log.e("cdz","result="+MyJni.getString());
}

 

 

你可能感兴趣的:(笔记)