在Android studio中编写jni ndk接口并打jar包

开发环境: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、配置环境

  • 找到gradle.properties,在下面加上一行:android.deprecatedNdkCompileLease=1560756112233

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文件:

  •  打开命令行插件Terminal
  • 进入app/build/inermediates/classes/debug目录下
  • 使用命令javah 包名+类名 把.class文件编译成.h文件
  • 这个.h文件会生成在\app\build\intermediates\classes\debug目录下,我的.h文件叫com_example_aplex_jnidemo_JniNative.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、结束

 

 

 

 

 

 

 

你可能感兴趣的:(jni)