开发环境:Android Studio 3.0
1、新建一个Android Library工程
2、添加一个FingerprintJniLib类
3、编写FingerprintJniLib native接口
package com.zxy.fingerprint_jni_lib;
/**
* Created by admin on 2019/7/2.
*/
public class FingerprintJniLib {
static {
System.loadLibrary("fingerprint-jni-lib");
}
public static native void open();
}
4、配置环境
5、编译模块
1) 这里要注意:System.loadLibrary("fingerprint-jni-lib")会去data\data\packagname\lib下面去找fingerprint-jni-lib.so库
2)把.java文件编译成.class文件:选择整个项目,找到导航栏,做如下操作:Build->Make Modlues xxx。
3)把.class文件编译成.h文件:
4)新建jni目录,并将上述头文件复制到jni目录
5)添加Android.mk、Application.mk 、native.c
6)添加build.gradle编译选项,使用Android.mk、Application.mk去编译native.c而不是使用ndk,否则会出现
Android加载so出现dlopen failed: empty/missing DT_HASH in "libx.so" (built with --hash-style=gnu?)错误
编译配置如下:
defaultConfig {
minSdkVersion 19
targetSdkVersion 23
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
sourceSets.main{
jni.srcDirs=[]//禁用as自动生成mk
}
task ndkBuild(type:Exec,description:'Compile JNI source via NDK'){
commandLine "D:\\as\\sdk\\ndk-bundle\\ndk-build.cmd",//配置ndk的路径
'NDK_PROJECT_PATH=build/intermediates/ndk',//ndk默认的生成so的文件
'NDK_LIBS_OUT=src/main/jni',//配置的我们想要生成的so文件所在的位置
'APP_BUILD_SCRIPT=src/main/jni/Android.mk',//指定项目以这个mk的方式
'NDK_APPLOCATION_MK=src/main/jni/Application.mk'//指定项目以这个mk的方式
}
tasks.withType(JavaCompile){//使用ndkBuild
compileTask ->compileTask.dependsOn ndkBuild
}
}
6、源码
1)com_zxy_fingerprint_jni_lib_FingerprintJniLib.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class com_zxy_fingerprint_jni_lib_FingerprintJniLib */
#ifndef _Included_com_zxy_fingerprint_jni_lib_FingerprintJniLib
#define _Included_com_zxy_fingerprint_jni_lib_FingerprintJniLib
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_zxy_fingerprint_jni_lib_FingerprintJniLib
* Method: open
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_zxy_fingerprint_1jni_1lib_FingerprintJniLib_open
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
2)native.c
//
// Created by admin on 2019/7/1.
//
#include
#include
#include
/* Header for class com_zxy_mylibrary_JniNative */
#ifndef _Included_com_zxy_mylibrary_JniNative
#define _Included_com_zxy_mylibrary_JniNative
#include "android/log.h"
static const char *TAG="@native.c";
#define LOGE(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, ##args)
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_zxy_mylibrary_JniNative
* Method: hello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_zxy_fingerprint_1jni_1lib_FingerprintJniLib_open
(JNIEnv *env, jobject thiz)
{
LOGE("hello ,this is from Java_com_zxy_fingerprint_1jni_1lib_FingerprintJniLib_open\n");
}
JNINativeMethod method[]=
{
"hello", "()",(void *)Java_com_zxy_fingerprint_1jni_1lib_FingerprintJniLib_open,
};
#ifdef __cplusplus
}
#endif
#endif
3)Android.mk,添加LOCAL_LDFLAGS := -Wl,-hash-style=sysv防止报6中的错误
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := fingerprint-jni-lib
LOCAL_LDFLAGS := -Wl,-hash-style=sysv
LOCAL_LDLIBS := -llog
LOCAL_SRC_FILES := native.c
include $(BUILD_SHARED_LIBRARY)
4)Application.mk
APP_ABI:=x86,armeabi-v7a
7、编译模块生成so文件及jar包
so库文件放在了main/jni目录,jar包文件放在了build/intermediates/bundles/debug/classes.jar。
8、app中引用jar包及so文件
1)将classes.jar及so文件复制到libs目录
2)添加编译选项
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
defaultConfig {
applicationId "com.zxy.myjnidemo"
minSdkVersion 19
targetSdkVersion 23
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
//compile(name: 'mylibrary-debug', ext: 'aar')
implementation 'com.android.support:appcompat-v7:23.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:design:23.4.0'
implementation files('libs/classes.jar')
}
3)添加依赖关系app依赖classes.jar
4)应用
package com.zxy.myjnidemo;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import com.zxy.fingerprint_jni_lib.FingerprintJniLib;
public class MainActivity extends AppCompatActivity {
private FingerprintJniLib fpJni;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
fpJni = new FingerprintJniLib();
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
fpJni.open();
}
}
5)编译app,运行
12:46:36.996 2862-2862/com.zxy.myjnidemo E/@native.c: hello ,this is from Java_com_zxy_fingerprint_1jni_1lib_FingerprintJniLib_open
9、结束