Android studio封装调用多个第三方so动态库

1、在项目local.properties文件中配置NDK版本:
在这里插入图片描述
2、配置编译目录
在这里插入图片描述
cpp 目录为编译脚本,源代码和头文件目录
jniLibs 为第三方so库目录,

3、添加第三方so库
注意子目录名称按照so库编译模式命名;
编译模式:“armeabi”,“armeabi-v7a” ,“arm64-v8a”,“x86”,“x86_64” ,“mips”, “mips64”
在这里插入图片描述
4、添加jni的native的java调用类;
在这里插入图片描述
5、编辑JNI接口调用native的java文件

package com.signature.sdk;
public class SkfNative {
private static SkfNative mNative = null;
static {
System.loadLibrary(“c++_shared”);
System.loadLibrary(“JKLX_UKEY_GMAPI_TF”);
System.loadLibrary(“JKLX_UKEY_GMAPI_TF.bak”);
System.loadLibrary(“skf”);
}

public static SkfNative getInstance() {
	if (mNative == null) {
		mNative = new SkfNative();
	}
	return mNative;
}

/**
 * 初始化连接设备
 * @return 返回初始化连接结果
 */
public native int InitDevice();

/**
 * 反初始化断开设备
 * @return 返回反初始化断开设备结果
 */
public native int DeInitDevice();

}

6、编辑JNI接口调用native的cpp文件
在这里插入图片描述
7、添加第三方库的接口.h头文件
在这里插入图片描述

8、编辑JNI调用接口Native的cpp文件源码

#include <jni.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <android/log.h>

#include “include/SKF.h”
#include “include/SKF_define.h”
/* Header for class com_signature_sdk_SkfNative */

#ifndef _Included_com_signature_sdk_SkfNative
#define _Included_com_signature_sdk_SkfNative

#ifdef __cplusplus
extern “C” {
#endif

static const char *D_TAG=“LibSkfSignEncryLib”;
#define LOGD(fmt, args…) __android_log_print(ANDROID_LOG_DEBUG, D_TAG, fmt, ##args)
#define LOGW(fmt, args…) __android_log_print(ANDROID_LOG_WARN, D_TAG, fmt, ##args)
#define LOGE(fmt, args…) __android_log_print(ANDROID_LOG_ERROR, D_TAG, fmt, ##args)

static int MAX_LEN = 32;
static int INVALID_LEN = 8;

char pName[] = “Wosign-SmartClient-App-01”;
char pPin[] = “123456”;

HAPPLICATION* pApp = NULL;
DEVHANDLE* pDev = NULL;
HCONTAINER* pContainer = NULL;
HANDLE* pAgreeHandle = NULL;
HANDLE* pKeyHandle = NULL;
HANDLE* pEnHandle = NULL;
HANDLE* pDeHandle = NULL;
HANDLE* pDigestHandle = NULL;
HANDLE* pMacHandle = NULL;

/*

  • Class: com_signature_sdk_SkfNative

  • Method: InitDevice

  • Signature: ()I
    /
    JNIEXPORT jint JNICALL Java_com_signature_sdk_SkfNative_InitDevice(JNIEnv
    env, jobject obj)
    {
    ULONG ret = 0;
    BOOL bPresent = TRUE;
    int pSize = 256 * 160;

    ret = SKF_EnumDev(bPresent, NULL, (ULONG*)&pSize);
    if(ret != 0) {
    LOGD(“SKF_EnumDev(pSize) fail.”);
    return ret;
    }
    char nameList[pSize];
    ret = SKF_EnumDev(bPresent, nameList, (ULONG*)&pSize);
    if(pSize == 0) {
    LOGD(“SKF_EnumDev() none device.”);
    ret = -1001;
    return ret;
    }
    ret = SKF_ConnectDev(nameList, pDev);
    if(ret != 0) {
    LOGD(“SKF_ConnectDev() fail.”);
    return ret;
    }
    return ret;
    }

/*

  • Class: com_signature_sdk_SkfNative
  • Method: DeInitDevice
  • Signature: ()I
    /
    JNIEXPORT jint JNICALL Java_com_signature_sdk_SkfNative_DeInitDevice(JNIEnv
    env, jobject obj)
    {
    ULONG ret = 1;
    if(pDev == NULL) {
    LOGD(“DeInitDevice() pDev is null.”);
    return -1001;
    }
    ret = SKF_DisConnectDev(*pDev);
    return ret;
    }

#ifdef __cplusplus
}
#endif
#endif

9、添加Cmake的打包脚本文件CMakeLists.txt文件
在这里插入图片描述
10、编辑添加CMakeList.txt打包脚本

#设置cmake的最小版本
cmake_minimum_required(VERSION 3.10.2)
#设置编译输出类型
set(CMAKE_BUILD_TYPE Debug)
#set(CMAKE_BUILD_TYPE Release)
set(CMAKE_CXX_FLAGS_DEBUG “ E N V C X X F L A G S − O 0 − W a l l − g − g g d b − W l , − r p a t h = . / l i b s " ) s e t ( C M A K E C X X F L A G S R E L E A S E " ENV{CXXFLAGS} -O0 -Wall -g -ggdb -Wl,-rpath=./libs") set(CMAKE_CXX_FLAGS_RELEASE " ENVCXXFLAGSO0WallgggdbWl,rpath=./libs")set(CMAKECXXFLAGSRELEASE"ENV{CXXFLAGS} -O3 -Wl,-rpath=./libs”)

#设置第三方库头文件所在位置
include_directories(${CMAKE_SOURCE_DIR}/include)
#设置自定义封装的生成的so库
add_library( # Sets the name of the library.
skf

    # Sets the library as a shared library.
    SHARED

    # Provides a relative path to your source file(s).
    SkfSignEncryLib.cpp
    )

#添加自定义封装so库调用的第三方so库的头文件include目录
target_include_directories( # Specifies the target library.
skf

    PRIVATE
    # included in the NDK.
    ${CMAKE_SOURCE_DIR}/include
    )

#依赖的第三方.so/ .a库 (Android6.0和之后的版本添加.so/ .a库方式)
set(CMAKE_CXX_FLAGS “ C M A K E C X X F L A G S − L {CMAKE_CXX_FLAGS} -L CMAKECXXFLAGSL{CMAKE_SOURCE_DIR}/…/jniLibs/${ANDROID_ABI}”)

#依赖的第三方so库 (Android6.0之前的版本才支持该添加动态库方式)
#add_library(JKLX_UKEY_GMAPI_TF SHARED IMPORTED)
#set_target_properties( # Specifies the target library.

JKLX_UKEY_GMAPI_TF

# Specifies the parameter you want to define.

PROPERTIES IMPORTED_LOCATION

# Provides the path to the library you want to import.

${CMAKE_SOURCE_DIR}/…/jniLibs/armeabi-v7a/libJKLX_UKEY_GMAPI_TF.so

)

#add_library(JKLX_UKEY_GMAPI_TF.bak SHARED IMPORTED)
#set_target_properties( # Specifies the target library.

JKLX_UKEY_GMAPI_TF.bak

# Specifies the parameter you want to define.

PROPERTIES IMPORTED_LOCATION

# Provides the path to the library you want to import.

${CMAKE_SOURCE_DIR}/…/jniLibs/armeabi-v7a/libJKLX_UKEY_GMAPI_TF.bak.so

)

#add_library(c++_shared SHARED IMPORTED)
#set_target_properties( # Specifies the target library.

c++_shared

# Specifies the parameter you want to define.

PROPERTIES IMPORTED_LOCATION

# Provides the path to the library you want to import.

${CMAKE_SOURCE_DIR}/…/jniLibs/armeabi-v7a/libc++_shared.so

)

添加android系统库

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 )

#配置链接库,需要注意的是链接的顺序应该符合gcc链接的顺序规则,即被链接的库放在依赖它的库的后面,比如lib1依赖于lib2,lib2依赖于lib3,那么target_link_libraries(name lib1 lib2 lib3)。

target_link_libraries( # Specifies the target library.
skf

    # Links the target library to the log library
    JKLX_UKEY_GMAPI_TF
    JKLX_UKEY_GMAPI_TF.bak
    c++_shared

    # included in the NDK.
    ${log-lib}
    ${android-lib}
    )

=======================================================================================================

11、在Build.grade中添加编译配置
在这里插入图片描述
12、配置gradle编译设置
在这里插入图片描述

plugins {
id ‘com.android.application’
id ‘kotlin-android’
}

android {
compileSdkVersion 28
buildToolsVersion ‘28.0.3’

defaultConfig {
    applicationId "com.eloam.skfsignaturesdktest"
    minSdkVersion 21
    targetSdkVersion 26
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    externalNativeBuild {
        cmake {
            cppFlags "-frtti -fexceptions"
            abiFilters "armeabi-v7a"
        }
    }
    ndk{
        abiFilters "armeabi-v7a" /*, "arm64-v8a", "x86", "x86_64"*/
    }
}

sourceSets {
    main {
        jniLibs.srcDirs = ['src/main/jniLibs']
    }
}

externalNativeBuild {
    cmake {
        path "src/main/cpp/CMakeLists.txt"
    }
}

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}
compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
    jvmTarget = '1.8'
}

packagingOptions {
    pickFirst 'lib/armeabi-v7a/libc++_shared.so'
    pickFirst 'lib/armeabi-v7a/libJKLX_UKEY_GMAPI_TF.bak.so'
    pickFirst 'lib/armeabi-v7a/libJKLX_UKEY_GMAPI_TF.so'
}
//ndkVersion '21.1.6352462'

}

dependencies {
implementation fileTree(dir: ‘libs’, include: [‘.jar’,'.aar’])
implementation “org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version”
implementation ‘androidx.core:core-ktx:1.3.2’
implementation ‘androidx.appcompat:appcompat:1.2.0’
implementation ‘com.google.android.material:material:1.2.1’
implementation ‘androidx.constraintlayout:constraintlayout:2.0.4’
testImplementation ‘junit:junit:4.+’
androidTestImplementation ‘androidx.test.ext:junit:1.1.2’
androidTestImplementation ‘androidx.test.espresso:espresso-core:3.3.0’

//动态权限
implementation 'com.hjq:xxpermissions:6.2'

}

13、编译程序
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值